Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

first commit

  • Loading branch information...
commit 7d2c1340b5236c2d77c241394868527f546601ad 0 parents
@jhaynie jhaynie authored
Showing with 10,295 additions and 0 deletions.
  1. +2 −0  .gitignore
  2. +248 −0 LICENSE
  3. +31 −0 README.md
  4. +22 −0 bin/titanium
  5. +113 −0 lib/titanium.js
  6. +24 −0 lib/titanium/analytics.js
  7. +18 −0 lib/titanium/builtins/builtins.js
  8. +122 −0 lib/titanium/builtins/help.js
  9. +25 −0 lib/titanium/builtins/login.js
  10. +24 −0 lib/titanium/builtins/logout.js
  11. +298 −0 lib/titanium/builtins/sdk.js
  12. +55 −0 lib/titanium/config.js
  13. +115 −0 lib/titanium/environ.js
  14. +180 −0 lib/titanium/externals/externals.js
  15. +104 −0 lib/titanium/log.js
  16. +68 −0 lib/titanium/path.js
  17. +20 −0 lib/titanium/string.js
  18. +1 −0  node_modules/.bin/asciimo
  19. +1 −0  node_modules/.bin/semver
  20. +1 −0  node_modules/.bin/unzip.js
  21. +22 −0 node_modules/colors/MIT-LICENSE.txt
  22. +77 −0 node_modules/colors/ReadMe.md
  23. +269 −0 node_modules/colors/colors.js
  24. +74 −0 node_modules/colors/example.html
  25. +65 −0 node_modules/colors/example.js
  26. +14 −0 node_modules/colors/package.json
  27. +65 −0 node_modules/colors/test.js
  28. +4 −0 node_modules/optimist/.travis.yml
  29. +21 −0 node_modules/optimist/LICENSE
  30. +487 −0 node_modules/optimist/README.markdown
  31. +10 −0 node_modules/optimist/example/bool.js
  32. +7 −0 node_modules/optimist/example/boolean_double.js
  33. +7 −0 node_modules/optimist/example/boolean_single.js
  34. +8 −0 node_modules/optimist/example/default_hash.js
  35. +7 −0 node_modules/optimist/example/default_singles.js
  36. +8 −0 node_modules/optimist/example/divide.js
  37. +20 −0 node_modules/optimist/example/line_count.js
  38. +29 −0 node_modules/optimist/example/line_count_options.js
  39. +29 −0 node_modules/optimist/example/line_count_wrap.js
  40. +4 −0 node_modules/optimist/example/nonopt.js
  41. +2 −0  node_modules/optimist/example/reflect.js
  42. +3 −0  node_modules/optimist/example/short.js
  43. +11 −0 node_modules/optimist/example/string.js
  44. +19 −0 node_modules/optimist/example/usage-options.js
  45. +10 −0 node_modules/optimist/example/xup.js
  46. +475 −0 node_modules/optimist/index.js
  47. +1 −0  node_modules/optimist/node_modules/wordwrap/.npmignore
  48. +70 −0 node_modules/optimist/node_modules/wordwrap/README.markdown
  49. +10 −0 node_modules/optimist/node_modules/wordwrap/example/center.js
  50. +3 −0  node_modules/optimist/node_modules/wordwrap/example/meat.js
  51. +76 −0 node_modules/optimist/node_modules/wordwrap/index.js
  52. +37 −0 node_modules/optimist/node_modules/wordwrap/package.json
  53. +30 −0 node_modules/optimist/node_modules/wordwrap/test/break.js
  54. +63 −0 node_modules/optimist/node_modules/wordwrap/test/idleness.txt
  55. +31 −0 node_modules/optimist/node_modules/wordwrap/test/wrap.js
  56. +43 −0 node_modules/optimist/package.json
  57. +71 −0 node_modules/optimist/test/_.js
  58. +2 −0  node_modules/optimist/test/_/argv.js
  59. +3 −0  node_modules/optimist/test/_/bin.js
  60. +420 −0 node_modules/optimist/test/parse.js
  61. +292 −0 node_modules/optimist/test/usage.js
  62. +2 −0  node_modules/pkginfo/.npmignore
  63. +85 −0 node_modules/pkginfo/README.md
  64. +194 −0 node_modules/pkginfo/docs/docco.css
  65. +101 −0 node_modules/pkginfo/docs/pkginfo.html
  66. +19 −0 node_modules/pkginfo/examples/all-properties.js
  67. +20 −0 node_modules/pkginfo/examples/array-argument.js
  68. +19 −0 node_modules/pkginfo/examples/multiple-properties.js
  69. +22 −0 node_modules/pkginfo/examples/object-argument.js
  70. +10 −0 node_modules/pkginfo/examples/package.json
  71. +19 −0 node_modules/pkginfo/examples/single-property.js
  72. +132 −0 node_modules/pkginfo/lib/pkginfo.js
  73. +17 −0 node_modules/pkginfo/package.json
  74. +69 −0 node_modules/pkginfo/test/pkginfo-test.js
  75. +55 −0 node_modules/request/LICENSE
  76. +287 −0 node_modules/request/README.md
  77. +103 −0 node_modules/request/forever.js
  78. +913 −0 node_modules/request/main.js
  79. +152 −0 node_modules/request/mimetypes.js
  80. +34 −0 node_modules/request/oauth.js
  81. +15 −0 node_modules/request/package.json
  82. BIN  node_modules/request/tests/googledoodle.png
  83. +38 −0 node_modules/request/tests/run.js
  84. +82 −0 node_modules/request/tests/server.js
  85. +77 −0 node_modules/request/tests/squid.conf
  86. +20 −0 node_modules/request/tests/ssl/ca/ca.cnf
  87. 0  node_modules/request/tests/ssl/ca/ca.crl
  88. +17 −0 node_modules/request/tests/ssl/ca/ca.crt
  89. +13 −0 node_modules/request/tests/ssl/ca/ca.csr
  90. +18 −0 node_modules/request/tests/ssl/ca/ca.key
  91. +1 −0  node_modules/request/tests/ssl/ca/ca.srl
  92. +19 −0 node_modules/request/tests/ssl/ca/server.cnf
  93. +16 −0 node_modules/request/tests/ssl/ca/server.crt
  94. +11 −0 node_modules/request/tests/ssl/ca/server.csr
  95. +28 −0 node_modules/request/tests/ssl/ca/server.js
  96. +9 −0 node_modules/request/tests/ssl/ca/server.key
  97. +16 −0 node_modules/request/tests/ssl/npm-ca.crt
  98. +15 −0 node_modules/request/tests/ssl/test.crt
  99. +15 −0 node_modules/request/tests/ssl/test.key
  100. +95 −0 node_modules/request/tests/test-body.js
  101. +29 −0 node_modules/request/tests/test-cookie.js
  102. +90 −0 node_modules/request/tests/test-cookiejar.js
  103. +68 −0 node_modules/request/tests/test-defaults.js
  104. +37 −0 node_modules/request/tests/test-errors.js
  105. +52 −0 node_modules/request/tests/test-headers.js
  106. +94 −0 node_modules/request/tests/test-httpModule.js
  107. +97 −0 node_modules/request/tests/test-https-strict.js
  108. +86 −0 node_modules/request/tests/test-https.js
  109. +117 −0 node_modules/request/tests/test-oauth.js
  110. +92 −0 node_modules/request/tests/test-params.js
  111. +202 −0 node_modules/request/tests/test-pipes.js
  112. +39 −0 node_modules/request/tests/test-proxy.js
  113. +28 −0 node_modules/request/tests/test-qs.js
  114. +154 −0 node_modules/request/tests/test-redirect.js
  115. +87 −0 node_modules/request/tests/test-timeout.js
  116. +14 −0 node_modules/request/tests/test-toJSON.js
  117. +61 −0 node_modules/request/tests/test-tunnel.js
  118. +229 −0 node_modules/request/tunnel.js
  119. +19 −0 node_modules/request/uuid.js
  120. +65 −0 node_modules/request/vendor/cookie/index.js
  121. +72 −0 node_modules/request/vendor/cookie/jar.js
  122. +23 −0 node_modules/semver/LICENSE
  123. +119 −0 node_modules/semver/README.md
  124. +71 −0 node_modules/semver/bin/semver
  125. +11 −0 node_modules/semver/package.json
  126. +305 −0 node_modules/semver/semver.js
  127. +397 −0 node_modules/semver/test.js
  128. +4 −0 node_modules/temp/.npmignore
  129. +20 −0 node_modules/temp/LICENSE
  130. +176 −0 node_modules/temp/README.md
  131. +18 −0 node_modules/temp/examples/grepcount.js
  132. +22 −0 node_modules/temp/examples/pdfcreator.js
  133. +144 −0 node_modules/temp/lib/temp.js
  134. +28 −0 node_modules/temp/package.json
  135. +52 −0 node_modules/temp/test/temp-test.js
  136. +44 −0 package.json
2  .gitignore
@@ -0,0 +1,2 @@
+npm-debug.log
+
248 LICENSE
@@ -0,0 +1,248 @@
+======================================
+Appcelerator Titanium CLI
+Copyright (c) 2012 Appcelerator, Inc.
+======================================
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ (or the full text of the license is below)
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+
+PRIVACY NOTICE
+==============
+
+At Appcelerator, we’re committed to transparency and we respect your privacy.
+This software collects information about you and your end-users of any
+applications that you build. The information we collect is used to
+improve the content of our Products, Websites and Applications built using
+our technology (collectively and individually, the "Software"), used to
+customize the content and/or layout of our Software for each individual
+visitor, used to notify users about updates to our Software, used by us to
+contact users for marketing purposes, disclosed when legally required to
+do so, at the request of governmental authorities conducting an investigation,
+to verify or enforce compliance with the policies governing our Software and
+applicable laws or to protect against misuse or unauthorized use of our
+Software, to a successor entity in connection with a corporate merger,
+consolidation, sale of assets or other corporate change respecting the
+Software.
+
+
+Please review the full text of our privacy policy online at:
+<http://www.appcelerator.com/company/privacy/>
+
+
31 README.md
@@ -0,0 +1,31 @@
+## Overview
+
+[Titanium](https://github.com/appcelerator/titanium) is a [Command Line Tool (CLI)](http://en.wikipedia.org/wiki/Command-line_interface) for managing and deploying Titanium mobile applications and modules. It's open-source and easy to use. [We've](https://github.com/appcelertor) designed `titanium` to be suitable for command line beginners, but still be powerful and extensible enough for production usage.
+
+`titanium` requires `npm`, the [node package manager](http://npmjs.org).
+
+## One-line npm install
+
+ [sudo] curl http://npmjs.org/install.sh | sh
+
+
+## One-line titanium install
+
+ [sudo] npm install titanium -g
+
+<a name="Libraries"></a>
+## Libraries
+`titanium` is built on a few well developed, well maintained Node.js libraries.
+
+- [npm](http://npmjs.org) - Node Package Manager
+- [colors](https://github.com/marak/colors.js) - Terminal Colors module
+- [optimist](https://github.com/substack/node-optimist) - CLI Options Parsing
+
+
+<a name="License"></a>
+## License
+
+This project is open source and provided under the Apache Public License (version 2). Please make sure you see the `LICENSE` file
+included in this distribution for more details on the license. Also, please take notice of the privacy notice at the end of the file.
+
+#### (C) Copyright 2012, [Appcelerator](http://www.appcelerator.com) Inc. All Rights Reserved.
22 bin/titanium
@@ -0,0 +1,22 @@
+#!/usr/bin/env node
+
+var titanium = require('../lib/titanium');
+
+titanium.start(function (err)
+{
+
+ process.stdout.on('drain', function () {
+// process.exit(err ? 1 : 0);
+ })
+
+ function onexit (code, status) {
+ if (err) {
+ process.removeListener('exit', onexit);
+ process.exit(code);
+ }
+ }
+
+ process.on('exit', onexit);
+
+});
+
113 lib/titanium.js
@@ -0,0 +1,113 @@
+/*
+ * titanium.js: Top-level include for the titanium CLI
+ *
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+console.log('hello');
+
+
+var path = require("path"),
+ colors = require("colors"),
+ optimist = require("optimist"),
+ fs = require("fs"),
+ environ = require('./titanium/environ.js'),
+ config = require('./titanium/config.js'),
+ builtins = require('./titanium/builtins/builtins.js').builtins
+ externals = require('./titanium/externals/externals.js').externals,
+ log = require('./titanium/log.js'),
+ analytics = require('./titanium/analytics.js'),
+ pkginfo = require('pkginfo')(module, 'name', 'version');
+
+var titanium = module.exports;
+
+function banner()
+{
+ // yes, that's correct: ascii art FTW
+ var prompt = [
+ "________ __ ",
+ "___ __/___(_)__ /_______ ________ ___(_)____ _________ ___",
+ " / / __ / _ __/_ __ `/__ __ \\__ / _ / / /__ __ `__ \\",
+ " / / _ / / /_ / /_/ / _ / / /_ / / /_/ / _ / / / / /",
+ "/_/ /_/ \\__/ \\__,_/ /_/ /_/ /_/ \\__,_/ /_/ /_/ /_/"
+ ];
+ console.log(prompt.join("\n").cyan);
+ console.log();
+ console.log("Welcome to ".white + "Titanium".bold.cyan + " - the open source mobile framework by".white + " Appcelerator".red.bold+" and contributors".white);
+ console.log();
+}
+
+titanium.start = function(setup)
+{
+ setup();
+
+ var cmd = optimist.argv._[0];
+ var args = optimist.argv._.splice(1);
+ var showBanner = optimist.argv.banner===false ? false : true;
+
+ if (optimist.argv._.length < 1)
+ {
+ cmd = 'help';
+ }
+ if (optimist.argv.version && cmd=='help' || (cmd=='help' && args[0]=='version'))
+ {
+ args = ['version'];
+ showBanner = false;
+ }
+
+ // turn off the colors
+ if (optimist.argv.colors === false || config.config.colors === false)
+ {
+ colors.mode = "none";
+ }
+
+ // turn off the analytics
+ if (optimist.argv.analytics === false || config.config.analytics === false)
+ {
+ analytics.on = false;
+ }
+
+ // check for quiet settings
+ if (optimist.argv.quiet)
+ {
+ log.quiet = true;
+ showBanner = false;
+ }
+
+ if (showBanner)
+ {
+ banner();
+ }
+
+ // see if we have a log file
+ if (optimist.argv.logpath || config.config.logpath)
+ {
+ log.logpath = optimist.argv.logpath || config.config.logpath;
+ log.configure(cmd!='help');
+ }
+
+ if (!environ.ok)
+ {
+ //TODO: it would be nice to allow the user to install titanium directly from here
+ log.error("It appears that no Titanium Mobile SDK could be found on this system. Please make sure to install before continuing.");
+ }
+
+ if (builtins[cmd])
+ {
+ require('./titanium/builtins/'+cmd+'.js').execute(module,environ,config.config,args,optimist.argv);
+ }
+ else if (externals[cmd])
+ {
+ require('./titanium/externals/externals.js').execute(module,environ,config.config,args,optimist.argv,cmd);
+ }
+ else
+ {
+ log.error("Couldn't find command: " + cmd.grey.bold + ". You can run " + "titanium help commands".cyan.bold + " to get a list of all commands",2);
+ }
+
+
+ // TEST
+ // config.config['b']=0xabc;
+ // config.saveConfig();
+};
+
24 lib/titanium/analytics.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+var config = require('./config.js').config;
+
+function addEvent (name,payload)
+{
+ // allow the analytics to be turned off
+ if (config.analytics === false || module.exports.on === false)
+ {
+ return;
+ }
+
+ // TODO: implement logging
+
+ // ideally we would store to a local SQLite (or JSON file) and
+ // send when connected and store when not connected for later sending
+ // this would be similar to what we do on the phone
+}
+
+module.exports.addEvent = addEvent;
+module.exports.on = true;
18 lib/titanium/builtins/builtins.js
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+
+/**
+ * these are the built-in commands that are handled and packaged with each version of the
+ * CLI instead of delegated to the SDK itself (which are called externals).
+ */
+
+module.exports.builtins =
+{
+ 'help': "provide usage information for this tool",
+ 'sdk': "manage SDK versions (download, list)",
+ 'login': "login to the Appcelerator cloud",
+ 'logout': "logout of the Appcelerator cloud"
+};
122 lib/titanium/builtins/help.js
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+/**
+ * command: help
+ * purpose: display help for this CLI
+ *
+ */
+var builtins = require('./builtins.js').builtins,
+ externals = require('../externals/externals.js').externals,
+ log = require('../log.js'),
+ string = require('../string.js');
+
+
+function help(titanium, environ, config, args, params)
+{
+ // print any additional arguments
+ console.log([
+ "Sub-commands:".cyan.bold.underline,
+ "",
+ " " + string.rpad("version",15) + "print the version of the CLI".grey,
+ " " + string.rpad("commands",15) + "print all available commands".grey,
+ ].join("\n"));
+ console.log();
+}
+
+function execute (titanium, environ, config, args, params)
+{
+ if (args.length > 0)
+ {
+ var cmd = args[0];
+
+ if (builtins[cmd])
+ {
+ console.log("Command:".cyan.bold.underline);
+ console.log();
+ console.log(' ' + string.rpad(cmd,15) + builtins[cmd].grey);
+ console.log();
+ require('./'+cmd+'.js').help(titanium, environ, config, args, params, cmd);
+ }
+ else if (externals[cmd])
+ {
+ console.log("Command:".cyan.bold.underline);
+ console.log();
+ console.log(' ' + string.rpad(cmd,15) + externals[cmd].grey);
+ console.log();
+ require('../externals/externals.js').help(titanium, environ, config, args, params, cmd);
+ }
+ else if (cmd == 'version')
+ {
+ console.log(titanium.exports.version);
+ }
+ else if (cmd == 'commands')
+ {
+ // make a listing of all available commands
+ var commands = [];
+ for (var k in builtins) { commands.push(' ' + string.rpad(k,15) + builtins[k].grey) }
+ for (var k in externals) { commands.push(' ' + string.rpad(k,15) + externals[k].grey) }
+ var prompt = [
+ "Available Commands:".cyan.underline.bold,
+ "",
+ commands.join("\n"),
+ ""
+ ];
+ console.log(prompt.join("\n"));
+ }
+ else
+ {
+ // don't have that command
+ log.error("I don't support the command "+cmd.red.bold);
+ }
+ }
+ else
+ {
+ var prompt = [
+ "Usage:".cyan.underline.bold,
+ "",
+ " titanium [command] <arguments>",
+ "",
+ "",
+ "Common Commands:".cyan.underline.bold,
+ "",
+ "To install latest SDK".cyan,
+ " titanium sdk install",
+ "",
+ "To create a project".cyan,
+ " titanium create",
+ "",
+ "To build a project".cyan,
+ " titanium build",
+ "",
+ "To run a project".cyan,
+ " titanium run",
+ "",
+ "To install a project".cyan,
+ " titanium install",
+ // "",
+ // "Other Commands:".cyan.underline.bold,
+ // " titanium login " + "login of the Appcelerator cloud".grey,
+ // " titanium logout " + "logout of the Appcelerator cloud".grey,
+ // " titanium clean " + "fully clean project removing all generated files".grey,
+ // " titanium help " + "get a detailed listing of all available commands".grey,
+ // "",
+ "To get a list of all available commands: ".cyan + "titanium help commands",
+ "",
+ "Common Examples:".cyan.underline.bold,
+ "",
+ "To create a titanium app for iOS, Android and Mobile Web".cyan,
+ " titanium create --platforms=ios,android,mobileweb --id=org.appcelerator.sample sample",
+ "",
+ "To build the project".cyan,
+ " titanium build --platforms=ios sample",
+ ""
+ ];
+ console.log(prompt.join("\n"));
+ }
+}
+
+module.exports.execute = execute;
+module.exports.help = help;
25 lib/titanium/builtins/login.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+/**
+ * command: login
+ * purpose: login to the appcelerator cloud
+ *
+ */
+
+function help(titanium, environ, config, args, params)
+{
+ // print any additional arguments
+}
+
+
+function execute (titanium, environ, config, args, params)
+{
+ // do the login
+ // cache the credentials for offline access
+}
+
+module.exports.help = help;
+module.exports.execute = execute;
24 lib/titanium/builtins/logout.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+/**
+ * command: logout
+ * purpose: logout of the appcelerator cloud
+ *
+ */
+
+function help(titanium, environ, config, args, params)
+{
+ // print any additional arguments
+}
+
+
+function execute (titanium, environ, config, args, params)
+{
+
+}
+
+module.exports.help = help;
+module.exports.execute = execute;
298 lib/titanium/builtins/sdk.js
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+
+/**
+ * command: download
+ * purpose: download the SDK
+ *
+ */
+
+/**
+ * TODO: need to support proxies (see jitsu for example of how they do it)
+ */
+
+var string = require('../string.js'),
+ log = require('../log.js'),
+ semver = require('semver'),
+ request = require('request'),
+ temp = require('temp'),
+ fs = require('fs'),
+ pathExists = require('../path.js').pathExists,
+ util = require('util'),
+ zip = require('zip'),
+ path = require("path"),
+ exec = require("child_process").exec;
+
+var branchesURL = 'http://builds.appcelerator.com.s3.amazonaws.com/mobile/branches.json';
+var branchURL = 'http://builds.appcelerator.com.s3.amazonaws.com/mobile/$BRANCH/index.json';
+var zipURL = 'http://builds.appcelerator.com.s3.amazonaws.com/mobile/';
+var releaseURL = 'http://api.appcelerator.net/p/v1/release-list';
+
+function help(titanium, environ, config, args, params)
+{
+ // print any additional arguments
+ console.log([
+ "Sub-commands:".cyan.bold.underline,
+ "",
+ " " + string.rpad("install <latest|VER>",25) + "download the latest version (default) or a specific version (or range)".grey,
+ " " + string.rpad("list",25) + "print a list of installed SDK versions".grey,
+ " " + string.rpad("update",25) + "check to find the latest version of the SDK".grey,
+ ].join("\n"));
+ console.log();
+}
+
+function progress(done)
+{
+ var cols = Math.min(80, process.stdout.getWindowSize()[0]);
+ var num = Math.floor(cols * done);
+ var str = '[' + string.rpad('',num,'#') + string.rpad('',cols-num,' ');
+ //TODO: windows
+ process.stdout.write('\x1b[?25l' + str + '] ' + String(((100*done).toFixed(0))+'%').grey + '\u000D');
+}
+
+function install (titanium, environ, config, args, params, details)
+{
+ var version = 'latest';
+ if (args.length > 1)
+ {
+ version = args[1];
+ }
+
+ if (!details)
+ {
+ request(releaseURL, function(error, response, body)
+ {
+ if (!error)
+ {
+ if (response.statusCode==200)
+ {
+ var r = JSON.parse(body);
+ var found = null;
+ for (var c=0;c<r.releases.length;c++)
+ {
+ if (environ.platform == r.releases[c].os)
+ {
+ if (version == 'latest' ||
+ r.releases[c].version == version)
+ {
+ if (version == 'latest') log.info('Latest version is '+r.releases[c].version.cyan);
+ found = r.releases[c];
+ break;
+ }
+ }
+ }
+ if (!found)
+ {
+ log.error("Couldn't find the requested version: "+version.cyan);
+ }
+ install(titanium, environ, config, args, params, found);
+ }
+ else
+ {
+ log.error("Didn't receive a valid response. Expected 200, received "+String(response.statusCode).cyan);
+ }
+ }
+ else
+ {
+ log.error('Error received from server: '+error.red);
+ }
+ });
+
+ }
+ else
+ {
+ log.debug('Using install version URL: ' + details.url.cyan);
+ var tempName = temp.path({suffix: '.zip'});
+ var tempStream = fs.createWriteStream(tempName);
+ var req = request(details.url);
+ var pipeResp =req.pipe(tempStream);
+ var done = 0, total = 0;
+ req.on('error',function(err){
+ fs.unlinkSync(tempName);
+ log.error('error retrieving download: ' +err.red);
+ });
+ req.on('response',function(req){
+ done = total = req.headers['content-length'];
+ });
+ req.on('data',function(buffer){
+ done -=buffer.length;
+ progress(1 - done/total);
+ });
+ tempStream.on('close',function(e){
+ process.stdout.write('\x1b[?12l\x1b[?25h\n');
+ log.debug('Retrieved '+String(total).cyan+' bytes into '+tempName.cyan);
+ extractSDK(titanium, environ, config, args, params, tempName, details.version||version);
+ });
+ }
+}
+
+function extractSDK(titanium, environ, config, args, params, file, version)
+{
+ if (!environ.ok)
+ {
+ // means we don't have an SDK installed. try to create our Titanium directory
+ if (!pathExists(environ.basedir))
+ {
+ log.debug("Attempting to setup the Titanium SDK directory at " + environ.basedir.cyan);
+ //TODO: better error checking and permissions checking
+ //TODO: windows, linux
+ fs.mkdirSync(environ.basedir);
+ }
+ }
+
+ //NOTE: this zip library doesn't seem to preserve file attributes (such as executable bit)
+ //so we're going to use normal unzip builtin to extract for unix-like OS
+ if (environ.platform == 'osx' || environ.platform == 'linux')
+ {
+ var cmd = 'unzip -of -qq "' + file + '" -d "' + environ.basedir + '"';
+ log.debug('Running: '+cmd.cyan);
+ log.info('Unzipping distribution file ... one moment');
+ exec(cmd, function(err, stdout, stderr){
+ if (err)
+ {
+ log.error(stderr);
+ log.error(err);
+ }
+ if (stdout) log.debug(stdout);
+ log.info("The " + version.cyan + " version of the SDK is now installed");
+ process.exit(0);
+ });
+ }
+ else
+ {
+ var data = fs.readFileSync(file);
+ var reader = zip.Reader(data);
+
+ reader.forEach(function (entry)
+ {
+ var pf = path.join(environ.basedir,entry.getName());
+ if (entry.isDirectory())
+ {
+ if (!pathExists(pf))
+ {
+ try { fs.mkdirSync(pf); } catch(e){}
+ }
+ }
+ else
+ {
+ log.debug(pf);
+ fs.writeFileSync(pf,entry.getData());
+ }
+ });
+
+ // delete the temporary file
+ fs.unlinkSync(file);
+ }
+}
+
+function list (titanium, environ, config, args, params)
+{
+ if (environ.sdk.length == 0)
+ {
+ console.log('No SDKs are installed');
+ return;
+ }
+ for (var c=0;c<environ.sdk.length;c++)
+ {
+ var meta = environ.sdk[c];
+ console.log(string.rpad(meta.version,20).cyan + meta.path.grey);
+ }
+}
+
+function update (titanium, environ, config, args, params)
+{
+ log.debug('Fetching update versions from '+branchesURL.grey);
+ request(releaseURL, function(error, response, body)
+ {
+ if (!error)
+ {
+ if (response.statusCode==200)
+ {
+ var r = JSON.parse(body);
+ var latest = null;
+ for (var c=0;c<r.releases.length;c++)
+ {
+ if (environ.platform == r.releases[c].os)
+ {
+ latest = r.releases[c];
+ break;
+ }
+ }
+ if (latest)
+ {
+ environ.sdk[0].version='1';
+ if(environ.sdk.length > 0 && environ.sdk[0].version == latest.version)
+ {
+ log.info('You have the latest version: '+latest.version.cyan.bold);
+ }
+ else
+ {
+ log.info('You do not have the latest version. The latest version is '+latest.version.cyan.bold);
+ if (params.install)
+ {
+ // DO THE INSTALL
+ log.info('Installing the latest version');
+ install(titanium, environ, config, args, params, latest);
+ }
+ else
+ {
+ log.info('You can automagically install the latest version when using this command such as ' + 'titanium sdk update --install'.cyan.bold);
+ }
+ }
+ }
+ }
+ else
+ {
+ log.error("Didn't receive a valid response. Expected 200, received "+String(response.statusCode).cyan);
+ }
+ }
+ else
+ {
+ log.error('Error received from server: '+error);
+ }
+ });
+}
+
+function execute (titanium, environ, config, args, params)
+{
+ if (args.length == 0)
+ {
+ log.error('please specify a sub-command or run '+'titanium help sdk'.cyan+' for specific help on this command');
+ }
+
+ // console.log(environ);
+ // process.exit(0);
+
+ var subcmd = args[0];
+
+ switch(subcmd)
+ {
+ case 'install':
+ {
+ install(titanium, environ, config, args, params);
+ break;
+ }
+ case 'list':
+ {
+ list(titanium, environ, config, args, params);
+ break;
+ }
+ case 'update':
+ {
+ update(titanium, environ, config, args, params);
+ break;
+ }
+ default:
+ {
+ log.error('unsupported sub-commana: ' + subcmd.cyan);
+ break;
+ }
+ }
+
+}
+
+module.exports.help = help;
+module.exports.execute = execute;
55 lib/titanium/config.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+var fs = require("fs"),
+ path = require("path"),
+ optimist = require("optimist"),
+ pathExists = require('./path.js').pathExists,
+ expandPath = require('./path.js').expandPath,
+ log = require('./log.js');
+
+function getConfigPath()
+{
+ if (process.platform == "win32") {
+ process.env.HOME = process.env.USERPROFILE;
+ }
+ var p = optimist.argv.config || path.join(process.env.HOME,'.ticli');
+ if (optimist.argv.config)
+ {
+ if (!pathExists(optimist.argv.config))
+ {
+ log.error("Could't find config path: "+optimist.argv.config.blue.bold.underline);
+ }
+ }
+ return expandPath(p);
+}
+
+var config = getConfigPath();
+
+function loadConfig()
+{
+ if (pathExists(config))
+ {
+ try
+ {
+ var b = fs.readFileSync(config,'utf-8');
+ return JSON.parse(b);
+ }
+ catch(e)
+ {
+ }
+ }
+ return {};
+}
+
+function saveConfig()
+{
+ fs.writeFileSync(config,JSON.stringify(module.exports.config),'utf-8');
+}
+
+module.exports.config = loadConfig();
+module.exports.saveConfig = saveConfig;
+
+
115 lib/titanium/environ.js
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+var pathExists = require('./path').pathExists;
+var listAndSortVersions = require('./path').listAndSortVersions;
+var fs = require('fs');
+var log = require('./log.js');
+
+function resolveTitaniumInstallPath()
+{
+ var path = require('path');
+ var platform = process.platform;
+
+ //
+ // Update env if using Windows
+ //
+ if (process.platform == "win32")
+ {
+ process.env.HOME = process.env.USERPROFILE;
+ }
+ else if (process.platform == "darwin")
+ {
+ platform = "osx";
+ }
+
+ // FIXME: we need to deal with non-OSX platforms
+
+ var targets = [
+ '~/Library/Application Support/Titanium',
+ '/Library/Application Support/Titanium'
+ ];
+
+ //FIXME: make this smart about the install path based on platform
+ var basedir = "/Library/Application Support/Titanium";
+
+ // construct an environ object which will contain the
+ // details of whats installed on the local machine
+ var config =
+ {
+ platform:platform,
+ basedir: basedir,
+ sdk:[],
+ modules:{},
+ ok:false
+ };
+ for (var c=0;c<targets.length;c++)
+ {
+ try
+ {
+ var dir = targets[c];
+ if (pathExists(dir))
+ {
+ var mobilesdkDir = path.join(dir,'mobilesdk',platform);
+ if (pathExists(mobilesdkDir))
+ {
+ var sdks = listAndSortVersions(mobilesdkDir);
+ config.sdk = [];
+ for (var x=0;x<sdks.length;x++)
+ {
+ config.sdk[x] = {version:sdks[x],path:path.join(mobilesdkDir,sdks[x])};
+ }
+ if (config.sdk.length > 0 && !config.ok)
+ {
+ config.ok = true;
+ }
+ }
+ var moduleDir = path.join(dir,'modules');
+ if (pathExists(moduleDir))
+ {
+ var modules = fs.readdirSync(moduleDir);
+ for (var x=0;x<modules.length;x++)
+ {
+ // skip older desktop modules
+ if (modules[x]=='win32' || modules[x]=='osx') continue;
+ // skip the mac magic stuff
+ if (modules[x]=='.DS_Store') continue;
+ var modulePath = path.join(moduleDir,modules[x]);
+ var moduleNames = fs.readdirSync(modulePath);
+ config.modules[modules[x]] = [];
+ for (var y=0;y<moduleNames.length;y++)
+ {
+ var i = moduleNames[y].indexOf('.zip');
+ var moduleName = moduleNames[y];
+ if (i==-1)
+ {
+ var moduleVers = fs.readdirSync(path.join(modulePath,moduleName));
+ var o = {};
+ o[moduleName]=moduleVers;
+ config.modules[modules[x]].push(o);
+ }
+ else
+ {
+ var t = moduleName.substring(0,moduleName.length-4).split('-');
+ var o = {};
+ o[t[0]]=[t[2]];
+ config.modules[t[1]].push(o);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch(e)
+ {
+ // oops...
+ log.error(e);
+ }
+ }
+
+ return config;
+}
+
+module.exports = resolveTitaniumInstallPath();
180 lib/titanium/externals/externals.js
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+
+var log = require('../log.js'),
+ pathExists = require('../path.js').pathExists,
+ expandPath = require("../path.js").expandPath,
+ path = require('path'),
+ string = require('../string.js'),
+ fs = require('fs'),
+ analytics = require('../analytics.js');
+
+/**
+ * these are the external commands that delegated to the SDK itself instead of packaged with the
+ * CLI. this module will handle the delegation to the appropriate implementation which is bundled
+ * inside each version of the SDK. we do this such that each version of the SDK can handle the
+ * version specific commands.
+ */
+
+// format: [command] [one liner description used by help]
+
+module.exports.externals =
+{
+ 'create': "create a new project",
+ 'build': "build a project",
+ 'install': "install the built app/module",
+ 'run': "run the built app/module",
+ 'clean': "clean the project removing all generated and temp files"
+};
+
+function resolveSDKVersion (titanium, environ, config, args, params)
+{
+ if (!environ.sdk || environ.sdk.length == 0)
+ {
+ log.error("No SDK versions detected",3);
+ }
+
+ var project_dir = expandPath(params.d || params.dir || process.env.PWD);
+
+ // SDK version resolution order:
+ //
+ // 1. look at the command line
+ // 2. look at tiapp.xml in current project
+ // 3. use the latest from environment
+ //
+
+ var ver = environ.sdk[0].version; // latest
+
+ if (params.version)
+ {
+ ver = params.version;
+ }
+ else
+ {
+ // check to see if the project directory is passed in and if not, assume the current working directory
+ var xml = path.join(project_dir,'tiapp.xml');
+ if (pathExists(xml))
+ {
+ // just do some poor man parsing which is fast
+ var fc = fs.readFileSync(xml,'utf-8');
+ var x = fc.indexOf('<sdk-version>');
+ if (x > 0)
+ {
+ var y = fc.indexOf('</sdk-version>',x);
+ ver = fc.substring(x+13,y);
+ }
+ }
+ }
+
+ // make sure we have the full path
+ var found = false;
+ var sdkPath = null;
+ for (var c=0;c<environ.sdk.length;c++)
+ {
+ if (environ.sdk[c].version == ver)
+ {
+ sdkPath = environ.sdk[c].path;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ log.error("Couldn't find the SDK version: " + ver.bold.cyan,3);
+ }
+
+ return {version:ver,path:sdkPath,projectDir:project_dir};
+}
+
+function help(titanium, environ, config, args, params, command)
+{
+ // print any additional arguments
+ var params = invoke('help', titanium, environ, config, args, params, command);
+ if (params)
+ {
+ console.log("Parameters:".cyan.bold.underline+"\n");
+ for (var c=0;c<params.length;c++)
+ {
+ console.log(" "+params[c]);
+ }
+ }
+}
+
+function execute (titanium, environ, config, args, params, command)
+{
+ invoke('execute', titanium, environ, config, args, params, command);
+}
+
+function requireParam(name, params)
+{
+ if (params[name])
+ {
+ return params[name];
+ }
+ log.error('Required parameter ' + name.cyan.bold + ' not found');
+}
+
+function optionalParam(name, params, def)
+{
+ if (typeof name == Object || typeof name == Array || String(typeof name)=='object')
+ {
+ for (var c=0;c<name.length;c++)
+ {
+ var r = optionalParam(name[c],params,null);
+ if (r)
+ {
+ return r;
+ }
+ }
+ return def;
+ }
+ if (params[name])
+ {
+ return params[name];
+ }
+ return def;
+}
+
+function invoke (_method, titanium, environ, config, args, params, command)
+{
+ var sdk = resolveSDKVersion(titanium, environ, config, args, params);
+
+ var commandDir = path.join(sdk.path,'cli-commands');
+
+ // make sure this SDK supports external commands
+ if (!pathExists(commandDir))
+ {
+ log.error("The "+sdk.version.cyan.bold+" of the SDK does not support this CLI tool",2);
+ }
+
+ // make sure this version of the SDK supports this command
+ var commandPath = path.join(commandDir,command,command+'.js');
+ if (!pathExists(commandPath))
+ {
+ log.error("The "+sdk.version.cyan.bold+" of the SDK appears to not support the command "+command.cyan.bold,2);
+ }
+
+ // provide a nice utils object that exposes our built-in utils that we want to give the externals
+ var utils = {
+ path: {
+ pathExists:pathExists,
+ expandPath:expandPath
+ },
+ log: log,
+ string: string,
+ sdk: sdk,
+ analytics: analytics,
+ require: requireParam,
+ optional: optionalParam
+ };
+
+ // delegate to our SDK command
+ return require(commandPath)[_method](titanium, environ, config, args, params, command, utils);
+}
+
+module.exports.help = help;
+module.exports.execute = execute;
104 lib/titanium/log.js
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+var fs = require('fs'),
+ colors = require('colors'),
+ expandPath = require('./path.js').expandPath;
+
+var fd;
+
+function log(msg)
+{
+ if (fd)
+ {
+ // strip the colors, we don't want them in a logfile
+ var m = colors.stripColors(msg);
+ fs.writeSync(fd, m + "\n");
+ }
+}
+
+function error (msg,exitCode)
+{
+ if (typeof msg === Array)
+ {
+ var newmsg = '';
+ for (var c=0;c<msg.length;c++)
+ {
+ if (!msg[c].color)
+ {
+ msg[c] = msg[c].grey;
+ }
+ newmsg+=msg[c] + ' ';
+ }
+ msg = newmsg;
+ }
+ var m = "[ERROR]".red.bold + " " + msg;
+ if (!module.exports.quiet)
+ {
+ console.error(m);
+ }
+ log(m);
+ cleanup();
+ process.exit(exitCode || 1);
+}
+
+function info (msg)
+{
+ var m = "[INFO] ".blue.bold + " " + msg;
+ if (!module.exports.quiet)
+ {
+ console.log(m);
+ }
+ log(m);
+}
+
+function debug (msg)
+{
+ var m = "[DEBUG]".grey.bold + " " + msg;
+ if (!module.exports.quiet)
+ {
+ console.log(m);
+ }
+ log(m);
+}
+
+function warn (msg)
+{
+ var m = "[WARN] ".magenta.bold + " " + msg;
+ if (!module.exports.quiet)
+ {
+ console.log(m);
+ }
+ log(m);
+}
+
+function configure(v)
+{
+ if (module.exports.logpath)
+ {
+ fd = fs.openSync(expandPath(module.exports.logpath),'w+');
+
+ process.on('exit', cleanup);
+
+ if (v) debug("Logging to file at " + module.exports.logpath.cyan.bold);
+ }
+}
+
+function cleanup()
+{
+ if (fd)
+ {
+ fs.closeSync(fd);
+ fd = null;
+ }
+}
+
+module.exports.error = error;
+module.exports.info = info;
+module.exports.debug = debug;
+module.exports.warn = warn;
+module.exports.configure = configure;
+module.exports.quiet = false;
+module.exports.logpath = null;
68 lib/titanium/path.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+var fs = require("fs"),
+ path = require("path");
+
+function expandPath(p)
+{
+ if (process.platform == "win32")
+ {
+ process.env.HOME = process.env.USERPROFILE;
+ }
+ var np = p.replace(/~\//g,process.env.HOME+'/');
+ return np;
+}
+
+function pathExists(dir)
+{
+ try
+ {
+ var d = expandPath(dir);
+ var stat = fs.statSync(d);
+ return stat && stat.size > 0;
+ }
+ catch(e)
+ {
+ return false;
+ }
+}
+
+function listAndSortVersions(dir)
+{
+ var listing = fs.readdirSync(dir);
+
+ var dirs = [];
+
+ // sort by OSGI version in reverse (newest) order first
+ for (var c=0;c<listing.length;c++)
+ {
+ dirs[c] = [listing[c],listing[c].replace(/\./g,'')];
+ }
+
+ var sortedDirs = dirs.sort(function(a,b){
+ if (a[0] == b[0]) return 0;
+ if (a[0] < b[0]) return 1;
+ return -1;
+ });
+
+ dirs = [];
+ for (var c=0;c<sortedDirs.length;c++)
+ {
+ // all of our SDKs contain a README
+ if (pathExists(path.join(dir,sortedDirs[c][0],'README')))
+ {
+ dirs.push(sortedDirs[c][0]);
+ }
+ }
+
+ return dirs;
+}
+
+
+
+module.exports.pathExists = pathExists;
+module.exports.listAndSortVersions = listAndSortVersions;
+module.exports.expandPath = expandPath;
20 lib/titanium/string.js
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012, Appcelerator, Inc. All Rights Reserved.
+ * See the LICENSE file for more information.
+ */
+
+function rpad(t, c, ch)
+{
+ if (!ch) ch = ' ';
+ var x = c - t.length;
+ if (x <= 0) return t;
+ var s = t;
+ for (var y=0;y<x;y++)
+ {
+ s+=ch;
+ }
+ return s;
+}
+
+
+module.exports.rpad = rpad;
1  node_modules/.bin/asciimo
1  node_modules/.bin/semver
1  node_modules/.bin/unzip.js
22 node_modules/colors/MIT-LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2010
+
+Marak Squires
+Alexis Sellier (cloudhead)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
77 node_modules/colors/ReadMe.md
@@ -0,0 +1,77 @@
+# colors.js - get color and style in your node.js console ( and browser ) like what
+
+<img src="http://i.imgur.com/goJdO.png" border = "0"/>
+
+
+## Installation
+
+ npm install colors
+
+## colors and styles!
+
+- bold
+- italic
+- underline
+- inverse
+- yellow
+- cyan
+- white
+- magenta
+- green
+- red
+- grey
+- blue
+- rainbow
+- zebra
+- random
+
+## Usage
+
+``` js
+var colors = require('./colors');
+
+console.log('hello'.green); // outputs green text
+console.log('i like cake and pies'.underline.red) // outputs red underlined text
+console.log('inverse the color'.inverse); // inverses the color
+console.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces)
+```
+
+# Creating Custom themes
+
+```js
+
+var require('colors');
+
+colors.setTheme({
+ silly: 'rainbow',
+ input: 'grey',
+ verbose: 'cyan',
+ prompt: 'grey',
+ info: 'green',
+ data: 'grey',
+ help: 'cyan',
+ warn: 'yellow',
+ debug: 'blue',
+ error: 'red'
+});
+
+// outputs red text
+console.log("this is an error".error);
+
+// outputs yellow text
+console.log("this is a warning".warn);
+```
+
+
+### Contributors
+
+Marak (Marak Squires)
+Alexis Sellier (cloudhead)
+mmalecki (Maciej Małecki)
+nicoreed (Nico Reed)
+morganrallen (Morgan Allen)
+JustinCampbell (Justin Campbell)
+ded (Dustin Diaz)
+
+
+#### , Marak Squires , Justin Campbell, Dustin Diaz (@ded)
269 node_modules/colors/colors.js
@@ -0,0 +1,269 @@
+/*
+colors.js
+
+Copyright (c) 2010
+
+Marak Squires
+Alexis Sellier (cloudhead)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+var isHeadless = false;
+
+if (typeof module !== 'undefined') {
+ isHeadless = true;
+}
+
+if (!isHeadless) {
+ var exports = {};
+ var module = {};
+ var colors = exports;
+ exports.mode = "browser";
+} else {
+ exports.mode = "console";
+}
+
+//
+// Prototypes the string object to have additional method calls that add terminal colors
+//
+var addProperty = function (color, func) {
+ var allowOverride = ['bold'];
+ exports[color] = function(str) {
+ return func.apply(str);
+ };
+ String.prototype.__defineGetter__(color, func);
+}
+
+//
+// Iterate through all default styles and colors
+//
+
+var x = ['bold', 'underline', 'italic', 'inverse', 'grey', 'black', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'];
+x.forEach(function (style) {
+
+ // __defineGetter__ at the least works in more browsers
+ // http://robertnyman.com/javascript/javascript-getters-setters.html
+ // Object.defineProperty only works in Chrome
+ addProperty(style, function () {
+ return stylize(this, style);
+ });
+});
+
+function sequencer(map) {
+ return function () {
+ if (!isHeadless) {
+ return this.replace(/( )/, '$1');
+ }
+ var exploded = this.split("");
+ var i = 0;
+ exploded = exploded.map(map);
+ return exploded.join("");
+ }
+}
+
+var rainbowMap = (function () {
+ var rainbowColors = ['red','yellow','green','blue','magenta']; //RoY G BiV
+ return function (letter, i, exploded) {
+ if (letter == " ") {
+ return letter;
+ } else {
+ return stylize(letter, rainbowColors[i++ % rainbowColors.length]);
+ }
+ }
+})();
+
+exports.addSequencer = function (name, map) {
+ addProperty(name, sequencer(map));
+}
+
+exports.addSequencer('rainbow', rainbowMap);
+exports.addSequencer('zebra', function (letter, i, exploded) {
+ return i % 2 === 0 ? letter : letter.inverse;
+});
+
+exports.setTheme = function (theme) {
+ Object.keys(theme).forEach(function(prop){
+ addProperty(prop, function(){
+ return exports[theme[prop]](this);
+ });
+ });
+}
+
+function stylize(str, style) {
+
+ if (exports.mode == 'console') {
+ var styles = {
+ //styles
+ 'bold' : ['\033[1m', '\033[22m'],
+ 'italic' : ['\033[3m', '\033[23m'],
+ 'underline' : ['\033[4m', '\033[24m'],
+ 'inverse' : ['\033[7m', '\033[27m'],
+ //grayscale
+ 'white' : ['\033[37m', '\033[39m'],
+ 'grey' : ['\033[90m', '\033[39m'],
+ 'black' : ['\033[30m', '\033[39m'],
+ //colors
+ 'blue' : ['\033[34m', '\033[39m'],
+ 'cyan' : ['\033[36m', '\033[39m'],
+ 'green' : ['\033[32m', '\033[39m'],
+ 'magenta' : ['\033[35m', '\033[39m'],
+ 'red' : ['\033[31m', '\033[39m'],
+ 'yellow' : ['\033[33m', '\033[39m']
+ };
+ } else if (exports.mode == 'browser') {
+ var styles = {
+ //styles
+ 'bold' : ['<b>', '</b>'],
+ 'italic' : ['<i>', '</i>'],
+ 'underline' : ['<u>', '</u>'],
+ 'inverse' : ['<span style="background-color:black;color:white;">', '</span>'],
+ //grayscale
+ 'white' : ['<span style="color:white;">', '</span>'],
+ 'grey' : ['<span style="color:grey;">', '</span>'],
+ 'black' : ['<span style="color:black;">', '</span>'],
+ //colors
+ 'blue' : ['<span style="color:blue;">', '</span>'],
+ 'cyan' : ['<span style="color:cyan;">', '</span>'],
+ 'green' : ['<span style="color:green;">', '</span>'],
+ 'magenta' : ['<span style="color:magenta;">', '</span>'],
+ 'red' : ['<span style="color:red;">', '</span>'],
+ 'yellow' : ['<span style="color:yellow;">', '</span>']
+ };
+ } else if (exports.mode == 'none') {
+ return str;
+ } else {
+ console.log('unsupported mode, try "browser", "console" or "none"');
+ }
+ return styles[style][0] + str + styles[style][1];
+};
+
+// don't summon zalgo
+addProperty('zalgo', function () {
+ return zalgo(this);
+});
+
+// please no
+function zalgo(text, options) {
+ var soul = {
+ "up" : [
+ '̍','̎','̄','̅',
+ '̿','̑','̆','̐',
+ '͒','͗','͑','̇',
+ '̈','̊','͂','̓',
+ '̈','͊','͋','͌',
+ '̃','̂','̌','͐',
+ '̀','́','̋','̏',
+ '̒','̓','̔','̽',
+ '̉','ͣ','ͤ','ͥ',
+ 'ͦ','ͧ','ͨ','ͩ',
+ 'ͪ','ͫ','ͬ','ͭ',
+ 'ͮ','ͯ','̾','͛',
+ '͆','̚'
+ ],
+ "down" : [
+ '̖','̗','̘','̙',
+ '̜','̝','̞','̟',
+ '̠','̤','̥','̦',
+ '̩','̪','̫','̬',
+ '̭','̮','̯','̰',
+ '̱','̲','̳','̹',
+ '̺','̻','̼','ͅ',
+ '͇','͈','͉','͍',
+ '͎','͓','͔','͕',
+ '͖','͙','͚','̣'
+ ],
+ "mid" : [
+ '̕','̛','̀','́',
+ '͘','̡','̢','̧',
+ '̨','̴','̵','̶',
+ '͜','͝','͞',
+ '͟','͠','͢','̸',
+ '̷','͡',' ҉'
+ ]
+ },
+ all = [].concat(soul.up, soul.down, soul.mid),
+ zalgo = {};
+
+ function randomNumber(range) {
+ r = Math.floor(Math.random()*range);
+ return r;
+ };
+
+ function is_char(character) {
+ var bool = false;
+ all.filter(function(i){
+ bool = (i == character);
+ });
+ return bool;
+ }
+
+ function heComes(text, options){
+ result = '';
+ options = options || {};
+ options["up"] = options["up"] || true;
+ options["mid"] = options["mid"] || true;
+ options["down"] = options["down"] || true;
+ options["size"] = options["size"] || "maxi";
+ var counts;
+ text = text.split('');
+ for(var l in text){
+ if(is_char(l)) { continue; }
+ result = result + text[l];
+
+ counts = {"up" : 0, "down" : 0, "mid" : 0};
+
+ switch(options.size) {
+ case 'mini':
+ counts.up = randomNumber(8);
+ counts.min= randomNumber(2);
+ counts.down = randomNumber(8);
+ break;
+ case 'maxi':
+ counts.up = randomNumber(16) + 3;
+ counts.min = randomNumber(4) + 1;
+ counts.down = randomNumber(64) + 3;
+ break;
+ default:
+ counts.up = randomNumber(8) + 1;
+ counts.mid = randomNumber(6) / 2;
+ counts.down= randomNumber(8) + 1;
+ break;
+ }
+
+ var arr = ["up", "mid", "down"];
+ for(var d in arr){
+ var index = arr[d];
+ for (var i = 0 ; i <= counts[index]; i++)
+ {
+ if(options[index]) {
+ result = result + soul[index][randomNumber(soul[index].length)];
+ }
+ }
+ }
+ }
+ return result;
+ };
+ return heComes(text);
+}
+
+addProperty('stripColors', function() {
+ return ("" + this).replace(/\u001b\[\d+m/g,'');
+});
74 node_modules/colors/example.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html lang="en-us">
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+ <title>Colors Example</title>
+ <script src="colors.js"></script>
+ </head>
+ <body>
+ <script>
+
+ var test = colors.red("hopefully colorless output");
+
+ document.write('Rainbows are fun!'.rainbow + '<br/>');
+ document.write('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported
+ document.write('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
+ //document.write('zalgo time!'.zalgo);
+ document.write(test.stripColors);
+ document.write("a".grey + " b".black);
+
+ document.write("Zebras are so fun!".zebra);
+
+ document.write(colors.rainbow('Rainbows are fun!'));
+ document.write(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported
+ document.write(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported
+ //document.write(colors.zalgo('zalgo time!'));
+ document.write(colors.stripColors(test));
+ document.write(colors.grey("a") + colors.black(" b"));
+
+ colors.addSequencer("america", function(letter, i, exploded) {
+ if(letter === " ") return letter;
+ switch(i%3) {
+ case 0: return letter.red;
+ case 1: return letter.white;
+ case 2: return letter.blue;
+ }
+ });
+
+ colors.addSequencer("random", (function() {
+ var available = ['bold', 'underline', 'italic', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'];
+
+ return function(letter, i, exploded) {
+ return letter === " " ? letter : letter[available[Math.round(Math.random() * (available.length - 1))]];
+ };
+ })());
+
+ document.write("AMERICA! F--K YEAH!".america);
+ document.write("So apparently I've been to Mars, with all the little green men. But you know, I don't recall.".random);
+
+ //
+ // Custom themes
+ //
+
+ colors.setTheme({
+ silly: 'rainbow',
+ input: 'grey',
+ verbose: 'cyan',
+ prompt: 'grey',
+ info: 'green',
+ data: 'grey',
+ help: 'cyan',
+ warn: 'yellow',
+ debug: 'blue',
+ error: 'red'
+ });
+
+ // outputs red text
+ document.write("this is an error".error);
+
+ // outputs yellow text
+ document.write("this is a warning".warn);
+
+ </script>
+ </body>
+</html>
65 node_modules/colors/example.js
@@ -0,0 +1,65 @@
+var colors = require('./colors');
+
+//colors.mode = "browser";
+
+var test = colors.red("hopefully colorless output");
+console.log('Rainbows are fun!'.rainbow);
+console.log('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported
+console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
+//console.log('zalgo time!'.zalgo);
+console.log(test.stripColors);
+console.log("a".grey + " b".black);
+
+console.log("Zebras are so fun!".zebra);
+
+console.log(colors.rainbow('Rainbows are fun!'));
+console.log(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported
+console.log(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported
+//console.log(colors.zalgo('zalgo time!'));
+console.log(colors.stripColors(test));
+console.log(colors.grey("a") + colors.black(" b"));
+
+colors.addSequencer("america", function(letter, i, exploded) {
+ if(letter === " ") return letter;
+ switch(i%3) {
+ case 0: return letter.red;
+ case 1: return letter.white;
+ case 2: return letter.blue;
+ }
+});
+
+colors.addSequencer("random", (function() {
+ var available = ['bold', 'underline', 'italic', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'];
+
+ return function(letter, i, exploded) {
+ return letter === " " ? letter : letter[available[Math.round(Math.random() * (available.length - 1))]];
+ };
+})());
+
+console.log("AMERICA! F--K YEAH!".america);
+console.log("So apparently I've been to Mars, with all the little green men. But you know, I don't recall.".random);
+
+//
+// Custom themes
+//
+
+colors.setTheme({
+ silly: 'rainbow',
+ input: 'grey',
+ verbose: 'cyan',
+ prompt: 'grey',
+ info: 'green',
+ data: 'grey',
+ help: 'cyan',
+ warn: 'yellow',
+ debug: 'blue',
+ error: 'red'
+});
+
+// outputs red text
+console.log("this is an error".error);
+
+// outputs yellow text
+console.log("this is a warning".warn);
+
+
14 node_modules/colors/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "colors",
+ "description": "get colors in your node.js console like what",
+ "version": "0.6.0-1",
+ "author": "Marak Squires",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/Marak/colors.js.git"
+ },
+ "engines": {
+ "node": ">=0.1.90"
+ },
+ "main": "colors"
+}
65 node_modules/colors/test.js
@@ -0,0 +1,65 @@
+var assert = require('assert'),
+ colors = require('./colors');
+
+//
+// This is a pretty nice example on how tests shouldn't be written. However,
+// it's more about API stability than about really testing it (although it's
+// a pretty complete test suite).
+//
+
+var s = 'string';
+
+function a(s, code) {
+ return '\033[' + code.toString() + 'm' + s + '\033[39m';
+}
+
+function aE(s, color, code) {
+ assert.equal(s[color], a(s, code));
+ assert.equal(colors[color](s), a(s, code));
+ assert.equal(s[color], colors[color](s));
+ assert.equal(s[color].stripColors, s);
+ assert.equal(s[color].stripColors, colors.stripColors(s));
+}
+
+function h(s, color) {
+ return '<span style="color:' + color + ';">' + s + '</span>';
+ // that's pretty dumb approach to testing it
+}
+
+var stylesColors = ['white', 'grey', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow'];
+var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']);
+
+colors.mode = 'console';
+assert.equal(s.bold, '\033[1m' + s + '\033[22m');
+assert.equal(s.italic, '\033[3m' + s + '\033[23m');
+assert.equal(s.underline, '\033[4m' + s + '\033[24m');
+assert.equal(s.inverse, '\033[7m' + s + '\033[27m');
+assert.ok(s.rainbow);
+aE(s, 'white', 37);
+aE(s, 'grey', 90);
+aE(s, 'black', 30);
+aE(s, 'blue', 34);
+aE(s, 'cyan', 36);
+aE(s, 'green', 32);
+aE(s, 'magenta', 35);
+aE(s, 'red', 31);
+aE(s, 'yellow', 33);
+assert.equal(s, 'string');
+
+colors.mode = 'browser';
+assert.equal(s.bold, '<b>' + s + '</b>');
+assert.equal(s.italic, '<i>' + s + '</i>');
+assert.equal(s.underline, '<u>' + s + '</u>');
+assert.equal(s.inverse, '<span style="background-color:black;color:white;">' + s + '</span>');
+assert.ok(s.rainbow);
+stylesColors.forEach(function (color) {
+ assert.equal(s[color], h(s, color));
+ assert.equal(colors[color](s), h(s, color));
+});
+
+colors.mode = 'none';
+stylesAll.forEach(function (style) {
+ assert.equal(s[style], s);
+ assert.equal(colors[style](s), s);
+});
+
4 node_modules/optimist/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.4
+ - 0.6
21 node_modules/optimist/LICENSE
@@ -0,0 +1,21 @@
+Copyright 2010 James Halliday (mail@substack.net)
+
+This project is free software released under the MIT/X11 license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+