From 110c6413e60da02d9e23736c1d04217454215e55 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 16 Jan 2019 17:53:38 +0100 Subject: [PATCH] premiere extention update --- pype/premiere/__init__.py | 5 +- pype/premiere/extensions/PProPanel/.debug | 2 +- pype/premiere/extensions/PProPanel/ext.js | 49 +- .../{pype_avalon => com.pype.avalon}/.debug | 6 +- .../.vscode/launch.json | 0 .../com.pype.avalon/CSXS/manifest.xml | 62 + .../ReadMe.md | 0 .../css/style.css | 0 .../extensions/com.pype.avalon/ext.js | 247 + .../index.html | 0 .../jsx/PPRO/PPro_API_Constants.jsx | 0 .../jsx/PPRO/Premiere.jsx | 400 +- .../com.pype.avalon/jsx/general.jsx | 19 + .../lib/CEPEngine_extensions.js | 0 .../lib/CSInterface.js | 0 .../lib/Vulcan.js | 0 .../lib/jquery-1.9.1.js | 0 .../com.pype.avalon/node_modules/glob/LICENSE | 15 + .../node_modules/glob/README.md | 368 + .../node_modules/glob/changelog.md | 67 + .../node_modules/glob/common.js | 240 + .../com.pype.avalon/node_modules/glob/glob.js | 790 ++ .../node_modules/glob/package.json | 76 + .../com.pype.avalon/node_modules/glob/sync.js | 486 + .../node_modules/jsonfile/.npmignore | 2 + .../node_modules/jsonfile/CHANGELOG.md | 126 + .../node_modules/jsonfile/LICENSE | 15 + .../node_modules/jsonfile/README.md | 162 + .../node_modules/jsonfile/appveyor.yml | 28 + .../node_modules/jsonfile/index.js | 133 + .../node_modules/jsonfile/package.json | 72 + .../node_modules/jsonify/README.markdown | 34 + .../node_modules/jsonify/index.js | 2 + .../node_modules/jsonify/lib/parse.js | 273 + .../node_modules/jsonify/lib/stringify.js | 154 + .../node_modules/jsonify/package.json | 90 + .../node_modules/jsonify/test/parse.js | 16 + .../node_modules/jsonify/test/stringify.js | 15 + .../node_modules/mkdirp/.npmignore | 2 + .../node_modules/mkdirp/.travis.yml | 5 + .../node_modules/mkdirp/LICENSE | 21 + .../node_modules/mkdirp/bin/cmd.js | 33 + .../node_modules/mkdirp/bin/usage.txt | 12 + .../node_modules/mkdirp/examples/pow.js | 6 + .../node_modules/mkdirp/index.js | 97 + .../mkdirp/node_modules/minimist/.travis.yml | 4 + .../mkdirp/node_modules/minimist/LICENSE | 18 + .../node_modules/minimist/example/parse.js | 2 + .../mkdirp/node_modules/minimist/index.js | 187 + .../mkdirp/node_modules/minimist/package.json | 101 + .../node_modules/minimist/readme.markdown | 73 + .../mkdirp/node_modules/minimist/test/dash.js | 24 + .../minimist/test/default_bool.js | 20 + .../node_modules/minimist/test/dotted.js | 16 + .../mkdirp/node_modules/minimist/test/long.js | 31 + .../node_modules/minimist/test/parse.js | 318 + .../minimist/test/parse_modified.js | 9 + .../node_modules/minimist/test/short.js | 67 + .../node_modules/minimist/test/whitespace.js | 8 + .../node_modules/mkdirp/package.json | 91 + .../node_modules/mkdirp/readme.markdown | 100 + .../node_modules/mkdirp/test/chmod.js | 38 + .../node_modules/mkdirp/test/clobber.js | 37 + .../node_modules/mkdirp/test/mkdirp.js | 26 + .../node_modules/mkdirp/test/opts_fs.js | 27 + .../node_modules/mkdirp/test/opts_fs_sync.js | 25 + .../node_modules/mkdirp/test/perm.js | 30 + .../node_modules/mkdirp/test/perm_sync.js | 34 + .../node_modules/mkdirp/test/race.js | 40 + .../node_modules/mkdirp/test/rel.js | 30 + .../node_modules/mkdirp/test/return.js | 25 + .../node_modules/mkdirp/test/return_sync.js | 24 + .../node_modules/mkdirp/test/root.js | 18 + .../node_modules/mkdirp/test/sync.js | 30 + .../node_modules/mkdirp/test/umask.js | 26 + .../node_modules/mkdirp/test/umask_sync.js | 30 + .../node_modules/mkpath/.npmignore | 1 + .../node_modules/mkpath/LICENSE | 7 + .../node_modules/mkpath/README.md | 27 + .../node_modules/mkpath/mkpath.js | 59 + .../node_modules/mkpath/package.json | 87 + .../node_modules/mkpath/test/chmod.js | 42 + .../node_modules/mkpath/test/clobber.js | 41 + .../node_modules/mkpath/test/mkpath.js | 32 + .../node_modules/mkpath/test/perm.js | 36 + .../node_modules/mkpath/test/perm_sync.js | 43 + .../node_modules/mkpath/test/rel.js | 36 + .../node_modules/mkpath/test/root.js | 22 + .../node_modules/mkpath/test/sync.js | 36 + .../node_modules/mkpath/test/umask.js | 32 + .../node_modules/mkpath/test/umask_sync.js | 36 + .../node_modules/node-png/.npmignore | 1 + .../node_modules/node-png/LICENSE | 19 + .../node_modules/node-png/README.md | 164 + .../node-png/examples/fromdocs.js | 26 + .../node_modules/node-png/examples/simple.js | 30 + .../node_modules/node-png/examples/test/bg.js | 27 + .../node-png/examples/test/bg.png | Bin 0 -> 93 bytes .../examples/test/img/PngSuite.LICENSE | 9 + .../examples/test/img/PngSuite.README | 25 + .../node-png/examples/test/img/basn0g08.png | Bin 0 -> 138 bytes .../node-png/examples/test/img/basn2c08.png | Bin 0 -> 145 bytes .../node-png/examples/test/img/basn3p08.png | Bin 0 -> 1286 bytes .../node-png/examples/test/img/basn4a08.png | Bin 0 -> 126 bytes .../node-png/examples/test/img/basn6a08.png | Bin 0 -> 184 bytes .../node-png/examples/test/img/f00n0g08.png | Bin 0 -> 319 bytes .../node-png/examples/test/img/f00n2c08.png | Bin 0 -> 2475 bytes .../node-png/examples/test/img/f01n0g08.png | Bin 0 -> 321 bytes .../node-png/examples/test/img/f01n2c08.png | Bin 0 -> 1180 bytes .../node-png/examples/test/img/f02n0g08.png | Bin 0 -> 355 bytes .../node-png/examples/test/img/f02n2c08.png | Bin 0 -> 1729 bytes .../node-png/examples/test/img/f03n0g08.png | Bin 0 -> 389 bytes .../node-png/examples/test/img/f03n2c08.png | Bin 0 -> 1291 bytes .../node-png/examples/test/img/f04n0g08.png | Bin 0 -> 269 bytes .../node-png/examples/test/img/f04n2c08.png | Bin 0 -> 985 bytes .../node-png/examples/test/img/tbrn2c08.png | Bin 0 -> 1633 bytes .../node-png/examples/test/img/tp0n0g08.png | Bin 0 -> 719 bytes .../node-png/examples/test/img/tp0n2c08.png | Bin 0 -> 1594 bytes .../node-png/examples/test/img/tp0n3p08.png | Bin 0 -> 1476 bytes .../node-png/examples/test/img/tp1n3p08.png | Bin 0 -> 1483 bytes .../node-png/examples/test/list.html | 38 + .../node-png/examples/test/out/.npmignore | 1 + .../node-png/examples/test/test.js | 38 + .../node_modules/node-png/lib/chunkstream.js | 200 + .../node_modules/node-png/lib/constants.js | 38 + .../node_modules/node-png/lib/crc.js | 79 + .../node_modules/node-png/lib/filter.js | 314 + .../node_modules/node-png/lib/packer.js | 110 + .../node_modules/node-png/lib/parser.js | 359 + .../node_modules/node-png/lib/png.js | 149 + .../node_modules/node-png/package.json | 59 + .../node_modules/open/.jshintignore | 2 + .../node_modules/open/.jshintrc | 27 + .../node_modules/open/.npmignore | 1 + .../com.pype.avalon/node_modules/open/LICENSE | 22 + .../node_modules/open/README.md | 33 + .../node_modules/open/lib/open.js | 63 + .../node_modules/open/package.json | 101 + .../node_modules/open/vendor/xdg-open | 767 ++ .../node_modules/request/CHANGELOG.md | 674 ++ .../node_modules/request/LICENSE | 55 + .../node_modules/request/README.md | 1115 ++ .../node_modules/request/index.js | 156 + .../node_modules/request/lib/auth.js | 168 + .../node_modules/request/lib/cookies.js | 39 + .../request/lib/getProxyFromURI.js | 79 + .../node_modules/request/lib/har.js | 215 + .../node_modules/request/lib/helpers.js | 66 + .../node_modules/request/lib/multipart.js | 113 + .../node_modules/request/lib/oauth.js | 148 + .../node_modules/request/lib/querystring.js | 51 + .../node_modules/request/lib/redirect.js | 157 + .../node_modules/request/lib/tunnel.js | 176 + .../node_modules/request/package.json | 166 + .../node_modules/request/request.js | 1565 +++ .../node_modules/walk/README.md | 307 + .../walk/lib/node-type-emitter.js | 89 + .../node_modules/walk/lib/walk-async-only.js | 93 + .../node_modules/walk/lib/walk.js | 301 + .../node_modules/walk/package.json | 78 + .../Effect Presets and Custom Items.prfpset | 0 .../payloads/PProPanel.mxi | 0 .../payloads/PProPanel.sqpreset | 0 .../payloads/Registry.png | Bin .../payloads/addons.png | Bin .../payloads/estk.png | Bin .../payloads/example.epr | 0 .../payloads/localhost.png | Bin .../payloads/onbeforeunload.html | 0 .../payloads/sequence_output_options.png | Bin .../payloads/test.jpg | Bin .../pype_avalon.jsx} | 4 +- .../extensions/com.pype.rename/.debug | 8 + .../com.pype.rename/.vscode/launch.json | 12 + .../CSXS/manifest.xml | 18 +- .../extensions/com.pype.rename/PypeRename.jsx | 66 + .../extensions/com.pype.rename/ReadMe.md | 215 + .../extensions/com.pype.rename/css/style.css | 46 + .../{pype_avalon => com.pype.rename}/ext.js | 0 .../extensions/com.pype.rename/index.html | 494 + .../jsx/PPRO/PPro_API_Constants.jsx | 60 + .../com.pype.rename/jsx/PPRO/Premiere.jsx | 2382 ++++ .../jsx/general.jsx | 0 .../extensions/com.pype.rename/launch.json | 12 + .../lib/CEPEngine_extensions.js | 699 ++ .../com.pype.rename/lib/CSInterface.js | 1291 +++ .../extensions/com.pype.rename/lib/Vulcan.js | 459 + .../com.pype.rename/lib/jquery-1.9.1.js | 9597 +++++++++++++++++ .../Effect Presets and Custom Items.prfpset | 122 + .../com.pype.rename/payloads/PProPanel.mxi | 20 + .../payloads/PProPanel.sqpreset | 41 + .../com.pype.rename/payloads/Registry.png | Bin 0 -> 228114 bytes .../com.pype.rename/payloads/addons.png | Bin 0 -> 783736 bytes .../com.pype.rename/payloads/estk.png | Bin 0 -> 69207 bytes .../com.pype.rename/payloads/example.epr | 4001 +++++++ .../com.pype.rename/payloads/localhost.png | Bin 0 -> 9910 bytes .../payloads/onbeforeunload.html | 343 + .../payloads/sequence_output_options.png | Bin 0 -> 51905 bytes .../com.pype.rename/payloads/test.jpg | Bin 0 -> 345752 bytes pype/vendor/pico/server.py | 27 +- pype/vendor/pysync.py | 6 +- pype/widgets/message_window.py | 4 +- 202 files changed, 34358 insertions(+), 258 deletions(-) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/.debug (52%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/.vscode/launch.json (100%) create mode 100644 pype/premiere/extensions/com.pype.avalon/CSXS/manifest.xml rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/ReadMe.md (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/css/style.css (100%) create mode 100644 pype/premiere/extensions/com.pype.avalon/ext.js rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/index.html (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/jsx/PPRO/PPro_API_Constants.jsx (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/jsx/PPRO/Premiere.jsx (94%) create mode 100644 pype/premiere/extensions/com.pype.avalon/jsx/general.jsx rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/lib/CEPEngine_extensions.js (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/lib/CSInterface.js (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/lib/Vulcan.js (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/lib/jquery-1.9.1.js (100%) create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/glob/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/glob/README.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/glob/changelog.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/glob/common.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/glob/glob.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/glob/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/glob/sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/.npmignore create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/CHANGELOG.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/README.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/appveyor.yml create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/index.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/README.markdown create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/index.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/parse.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/stringify.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/parse.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/stringify.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.npmignore create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.travis.yml create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/cmd.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/usage.txt create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/examples/pow.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/index.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/.travis.yml create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/example/parse.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/index.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/readme.markdown create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dash.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/default_bool.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dotted.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/long.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/short.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/whitespace.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/readme.markdown create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/chmod.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/clobber.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/mkdirp.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs_sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm_sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/race.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/rel.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return_sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/root.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask_sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/.npmignore create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/README.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/mkpath.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/chmod.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/clobber.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/mkpath.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm_sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/rel.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/root.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask_sync.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/.npmignore create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/README.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/fromdocs.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/simple.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/bg.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/bg.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.README create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn0g08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn3p08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn4a08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn6a08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f00n0g08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f00n2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f01n0g08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f01n2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f02n0g08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f02n2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f03n0g08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f03n2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f04n0g08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f04n2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tbrn2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n0g08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n2c08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n3p08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp1n3p08.png create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/list.html create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/out/.npmignore create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/test.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/chunkstream.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/constants.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/crc.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/filter.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/packer.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/parser.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/png.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/node-png/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintignore create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintrc create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/.npmignore create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/README.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/lib/open.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/open/vendor/xdg-open create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/CHANGELOG.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/LICENSE create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/README.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/index.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/auth.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/cookies.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/getProxyFromURI.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/har.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/helpers.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/multipart.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/oauth.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/querystring.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/redirect.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/tunnel.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/package.json create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/request/request.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/walk/README.md create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/node-type-emitter.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk-async-only.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk.js create mode 100644 pype/premiere/extensions/com.pype.avalon/node_modules/walk/package.json rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/Effect Presets and Custom Items.prfpset (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/PProPanel.mxi (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/PProPanel.sqpreset (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/Registry.png (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/addons.png (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/estk.png (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/example.epr (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/localhost.png (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/onbeforeunload.html (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/sequence_output_options.png (100%) rename pype/premiere/extensions/{pype_avalon => com.pype.avalon}/payloads/test.jpg (100%) rename pype/premiere/extensions/{pype_avalon/PProPanel.jsx => com.pype.avalon/pype_avalon.jsx} (94%) create mode 100644 pype/premiere/extensions/com.pype.rename/.debug create mode 100644 pype/premiere/extensions/com.pype.rename/.vscode/launch.json rename pype/premiere/extensions/{pype_avalon => com.pype.rename}/CSXS/manifest.xml (78%) create mode 100644 pype/premiere/extensions/com.pype.rename/PypeRename.jsx create mode 100644 pype/premiere/extensions/com.pype.rename/ReadMe.md create mode 100644 pype/premiere/extensions/com.pype.rename/css/style.css rename pype/premiere/extensions/{pype_avalon => com.pype.rename}/ext.js (100%) create mode 100644 pype/premiere/extensions/com.pype.rename/index.html create mode 100644 pype/premiere/extensions/com.pype.rename/jsx/PPRO/PPro_API_Constants.jsx create mode 100644 pype/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx rename pype/premiere/extensions/{pype_avalon => com.pype.rename}/jsx/general.jsx (100%) create mode 100644 pype/premiere/extensions/com.pype.rename/launch.json create mode 100644 pype/premiere/extensions/com.pype.rename/lib/CEPEngine_extensions.js create mode 100644 pype/premiere/extensions/com.pype.rename/lib/CSInterface.js create mode 100644 pype/premiere/extensions/com.pype.rename/lib/Vulcan.js create mode 100644 pype/premiere/extensions/com.pype.rename/lib/jquery-1.9.1.js create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/Effect Presets and Custom Items.prfpset create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/PProPanel.mxi create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/PProPanel.sqpreset create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/Registry.png create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/addons.png create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/estk.png create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/example.epr create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/localhost.png create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/onbeforeunload.html create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/sequence_output_options.png create mode 100644 pype/premiere/extensions/com.pype.rename/payloads/test.jpg diff --git a/pype/premiere/__init__.py b/pype/premiere/__init__.py index cc8c5d221e..3d6610795e 100644 --- a/pype/premiere/__init__.py +++ b/pype/premiere/__init__.py @@ -79,10 +79,10 @@ def install(): api.set_avalon_workdir() log.info("Registering Premiera plug-ins..") - reg_paths = request_aport("/pipeline/register_plugin_path", + reg_paths = request_aport("/api/register_plugin_path", {"publish_path": PUBLISH_PATH}) + log.info(str(reg_paths)) - api.message(title="pyblish_paths", message=str(reg_paths), level="info") avalon.register_plugin_path(avalon.Loader, LOAD_PATH) avalon.register_plugin_path(avalon.Creator, CREATE_PATH) @@ -102,6 +102,7 @@ def install(): # synchronize extensions extensions_sync() + api.message(title="pyblish_paths", message=str(reg_paths), level="info") def uninstall(): diff --git a/pype/premiere/extensions/PProPanel/.debug b/pype/premiere/extensions/PProPanel/.debug index 42782f0fdf..4a6cb49034 100644 --- a/pype/premiere/extensions/PProPanel/.debug +++ b/pype/premiere/extensions/PProPanel/.debug @@ -5,4 +5,4 @@ - \ No newline at end of file + diff --git a/pype/premiere/extensions/PProPanel/ext.js b/pype/premiere/extensions/PProPanel/ext.js index b7433a3443..6947e052c2 100644 --- a/pype/premiere/extensions/PProPanel/ext.js +++ b/pype/premiere/extensions/PProPanel/ext.js @@ -5,12 +5,13 @@ function onLoaded() { var appVersion = csInterface.hostEnvironment.appVersion; var APIVersion = csInterface.getCurrentApiVersion(); - + document.getElementById("dragthing").style.backgroundColor = "lightblue"; + var caps = csInterface.getHostCapabilities(); - + loadJSX(); - + updateThemeWithAppSkinInfo(csInterface.hostEnvironment.appSkinInfo); // Update the color of the panel when the theme color of the product changed. @@ -32,7 +33,7 @@ function onLoaded() { csInterface.evalScript('$._PPP_.closeLog()'); }); - + // register for messages VulcanInterface.addMessageListener( @@ -42,20 +43,20 @@ function onLoaded() { // You just received the text of every Text layer in the current AE comp. } ); - csInterface.evalScript('$._PPP_.getVersionInfo()', myVersionInfoFunction); - csInterface.evalScript('$._PPP_.getActiveSequenceName()', myCallBackFunction); - csInterface.evalScript('$._PPP_.getUserName()', myUserNameFunction); + csInterface.evalScript('$._PPP_.getVersionInfo()', myVersionInfoFunction); + csInterface.evalScript('$._PPP_.getActiveSequenceName()', myCallBackFunction); + csInterface.evalScript('$._PPP_.getUserName()', myUserNameFunction); csInterface.evalScript('$._PPP_.getProjectProxySetting()', myGetProxyFunction); csInterface.evalScript('$._PPP_.keepPanelLoaded()'); csInterface.evalScript('$._PPP_.disableImportWorkspaceWithProjects()'); - + csInterface.evalScript('$._PPP_.registerProjectPanelSelectionChangedFxn()'); // Project panel selection changed csInterface.evalScript('$._PPP_.registerItemAddedFxn()'); // Item added to project csInterface.evalScript('$._PPP_.registerProjectChangedFxn()'); // Project changed csInterface.evalScript('$._PPP_.registerSequenceSelectionChangedFxn()'); // Selection within the active sequence changed csInterface.evalScript('$._PPP_.confirmPProHostVersion()'); - + csInterface.evalScript('$._PPP_.clearESTKConsole()'); } @@ -63,7 +64,7 @@ function dragHandler(event){ var csInterface = new CSInterface(); var extPath = csInterface.getSystemPath(SystemPath.EXTENSION); var OSVersion = csInterface.getOSInformation(); - + if (extPath !== null){ extPath = extPath + '/payloads/test.jpg'; if (OSVersion.indexOf("Windows") >=0){ @@ -103,7 +104,7 @@ function mySetProxyFunction (data) { csInterface.evalScript('$._PPP_.getActiveSequenceName()', myCallBackFunction); csInterface.evalScript('$._PPP_.getProjectProxySetting()', myGetProxyFunction); } - + function myVersionInfoFunction (data) { var v_string = document.getElementById("version_string"); v_string.innerHTML = data; @@ -125,9 +126,9 @@ function updateThemeWithAppSkinInfo(appSkinInfo) { var gradientDisabledBg = "background-image: -webkit-linear-gradient(top, " + toHex(panelBackgroundColor, 15) + " , " + toHex(panelBackgroundColor, 5) + ");"; var boxShadow = "-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);"; var boxActiveShadow = "-webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);"; - + var isPanelThemeLight = panelBackgroundColor.red > 50; // choose your own sweet spot - + var fontColor, disabledFontColor; var borderColor; var inputBackgroundColor; @@ -146,16 +147,16 @@ function updateThemeWithAppSkinInfo(appSkinInfo) { inputBackgroundColor = toHex(panelBackgroundColor, -20) + ";"; gradientHighlightBg = "background-image: -webkit-linear-gradient(top, " + toHex(panelBackgroundColor, -20) + " , " + toHex(panelBackgroundColor, -30) + ");"; } - + //Update the default text style with pp values addRule(styleId, ".default", "font-size:" + appSkinInfo.baseFontSize + "px" + "; color:" + fontColor + "; background-color:" + toHex(panelBackgroundColor) + ";"); - addRule(styleId, "button, select, input[type=text], input[type=button], input[type=submit]", borderColor); - addRule(styleId, "p", "color:" + fontColor + ";"); - addRule(styleId, "button", "font-family: " + appSkinInfo.baseFontFamily + ", Arial, sans-serif;"); - addRule(styleId, "button", "color:" + fontColor + ";"); - addRule(styleId, "button", "font-size:" + (1.2 * appSkinInfo.baseFontSize) + "px;"); - addRule(styleId, "button, select, input[type=button], input[type=submit]", gradientBg); + addRule(styleId, "button, select, input[type=text], input[type=button], input[type=submit]", borderColor); + addRule(styleId, "p", "color:" + fontColor + ";"); + addRule(styleId, "button", "font-family: " + appSkinInfo.baseFontFamily + ", Arial, sans-serif;"); + addRule(styleId, "button", "color:" + fontColor + ";"); + addRule(styleId, "button", "font-size:" + (1.2 * appSkinInfo.baseFontSize) + "px;"); + addRule(styleId, "button, select, input[type=button], input[type=submit]", gradientBg); addRule(styleId, "button, select, input[type=button], input[type=submit]", boxShadow); addRule(styleId, "button:enabled:active, input[type=button]:enabled:active, input[type=submit]:enabled:active", gradientHighlightBg); addRule(styleId, "button:enabled:active, input[type=button]:enabled:active, input[type=submit]:enabled:active", boxActiveShadow); @@ -169,7 +170,7 @@ function updateThemeWithAppSkinInfo(appSkinInfo) { function addRule(stylesheetId, selector, rule) { var stylesheet = document.getElementById(stylesheetId); - + if (stylesheet) { stylesheet = stylesheet.sheet; if( stylesheet.addRule ){ @@ -211,13 +212,13 @@ function toHex(color, delta) { function onAppThemeColorChanged(event) { // Should get a latest HostEnvironment object from application. var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo; - // Gets the style information such as color info from the skinInfo, + // Gets the style information such as color info from the skinInfo, // and redraw all UI controls of your extension according to the style info. updateThemeWithAppSkinInfo(skinInfo); -} +} /** -* Load JSX file into the scripting context of the product. All the jsx files in +* Load JSX file into the scripting context of the product. All the jsx files in * folder [ExtensionRoot]/jsx & [ExtensionRoot]/jsx/[AppName] will be loaded. */ function loadJSX() { diff --git a/pype/premiere/extensions/pype_avalon/.debug b/pype/premiere/extensions/com.pype.avalon/.debug similarity index 52% rename from pype/premiere/extensions/pype_avalon/.debug rename to pype/premiere/extensions/com.pype.avalon/.debug index 42782f0fdf..9c2b3094ea 100644 --- a/pype/premiere/extensions/pype_avalon/.debug +++ b/pype/premiere/extensions/com.pype.avalon/.debug @@ -1,8 +1,8 @@ - + - + - \ No newline at end of file + diff --git a/pype/premiere/extensions/pype_avalon/.vscode/launch.json b/pype/premiere/extensions/com.pype.avalon/.vscode/launch.json similarity index 100% rename from pype/premiere/extensions/pype_avalon/.vscode/launch.json rename to pype/premiere/extensions/com.pype.avalon/.vscode/launch.json diff --git a/pype/premiere/extensions/com.pype.avalon/CSXS/manifest.xml b/pype/premiere/extensions/com.pype.avalon/CSXS/manifest.xml new file mode 100644 index 0000000000..7f047c466e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/CSXS/manifest.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + ./index.html + ./pype_avalon.jsx + + --allow-file-access + --allow-file-access-from-files + + + + true + + + Panel + Avalon + + + 300 + 400 + + + + + + + diff --git a/pype/premiere/extensions/pype_avalon/ReadMe.md b/pype/premiere/extensions/com.pype.avalon/ReadMe.md similarity index 100% rename from pype/premiere/extensions/pype_avalon/ReadMe.md rename to pype/premiere/extensions/com.pype.avalon/ReadMe.md diff --git a/pype/premiere/extensions/pype_avalon/css/style.css b/pype/premiere/extensions/com.pype.avalon/css/style.css similarity index 100% rename from pype/premiere/extensions/pype_avalon/css/style.css rename to pype/premiere/extensions/com.pype.avalon/css/style.css diff --git a/pype/premiere/extensions/com.pype.avalon/ext.js b/pype/premiere/extensions/com.pype.avalon/ext.js new file mode 100644 index 0000000000..6947e052c2 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/ext.js @@ -0,0 +1,247 @@ + +function onLoaded() { + var csInterface = new CSInterface(); + var appName = csInterface.hostEnvironment.appName; + var appVersion = csInterface.hostEnvironment.appVersion; + + var APIVersion = csInterface.getCurrentApiVersion(); + + document.getElementById("dragthing").style.backgroundColor = "lightblue"; + + var caps = csInterface.getHostCapabilities(); + + loadJSX(); + + updateThemeWithAppSkinInfo(csInterface.hostEnvironment.appSkinInfo); + + // Update the color of the panel when the theme color of the product changed. + csInterface.addEventListener(CSInterface.THEME_COLOR_CHANGED_EVENT, onAppThemeColorChanged); + // Listen for event sent in response to rendering a sequence. + csInterface.addEventListener("com.adobe.csxs.events.PProPanelRenderEvent", function(event){ + alert(event.data); + }); + + csInterface.addEventListener("com.adobe.csxs.events.WorkspaceChanged", function(event){ + alert("New workspace selected: " + event.data); + }); + + csInterface.addEventListener("com.adobe.ccx.start.handleLicenseBanner", function(event){ + alert("User chose to go \'Home\', wherever that is..."); + }); + + csInterface.addEventListener("ApplicationBeforeQuit", function(event){ + csInterface.evalScript('$._PPP_.closeLog()'); + }); + + + + // register for messages + VulcanInterface.addMessageListener( + VulcanMessage.TYPE_PREFIX + "com.DVA.message.sendtext", + function(message) { + var str = VulcanInterface.getPayload(message); + // You just received the text of every Text layer in the current AE comp. + } + ); + csInterface.evalScript('$._PPP_.getVersionInfo()', myVersionInfoFunction); + csInterface.evalScript('$._PPP_.getActiveSequenceName()', myCallBackFunction); + csInterface.evalScript('$._PPP_.getUserName()', myUserNameFunction); + csInterface.evalScript('$._PPP_.getProjectProxySetting()', myGetProxyFunction); + csInterface.evalScript('$._PPP_.keepPanelLoaded()'); + csInterface.evalScript('$._PPP_.disableImportWorkspaceWithProjects()'); + + csInterface.evalScript('$._PPP_.registerProjectPanelSelectionChangedFxn()'); // Project panel selection changed + csInterface.evalScript('$._PPP_.registerItemAddedFxn()'); // Item added to project + csInterface.evalScript('$._PPP_.registerProjectChangedFxn()'); // Project changed + csInterface.evalScript('$._PPP_.registerSequenceSelectionChangedFxn()'); // Selection within the active sequence changed + + csInterface.evalScript('$._PPP_.confirmPProHostVersion()'); + + csInterface.evalScript('$._PPP_.clearESTKConsole()'); +} + +function dragHandler(event){ + var csInterface = new CSInterface(); + var extPath = csInterface.getSystemPath(SystemPath.EXTENSION); + var OSVersion = csInterface.getOSInformation(); + + if (extPath !== null){ + extPath = extPath + '/payloads/test.jpg'; + if (OSVersion.indexOf("Windows") >=0){ + var sep = '\\\\'; + extPath = extPath.replace(/\//g, sep); + } + event.dataTransfer.setData("com.adobe.cep.dnd.file.0", extPath); + // event.dataTransfer.setData("com.adobe.cep.dnd.file.N", path); N = (items to import - 1) + } +} + +function myCallBackFunction (data) { + // Updates seq_display with whatever ExtendScript function returns. + var boilerPlate = "Active Sequence: "; + var seq_display = document.getElementById("active_seq"); + seq_display.innerHTML = boilerPlate + data; +} + +function myUserNameFunction (data) { + // Updates username with whatever ExtendScript function returns. + var user_name = document.getElementById("username"); + user_name.innerHTML = data; +} + +function myGetProxyFunction (data) { + // Updates proxy_display based on current sequence's value. + var boilerPlate = "Proxies enabled for project: "; + var proxy_display = document.getElementById("proxies_on"); + + if (proxy_display !== null) { + proxy_display.innerHTML = boilerPlate + data; + } +} + +function mySetProxyFunction (data) { + var csInterface = new CSInterface(); + csInterface.evalScript('$._PPP_.getActiveSequenceName()', myCallBackFunction); + csInterface.evalScript('$._PPP_.getProjectProxySetting()', myGetProxyFunction); +} + +function myVersionInfoFunction (data) { + var v_string = document.getElementById("version_string"); + v_string.innerHTML = data; +} + +/** + * Update the theme with the AppSkinInfo retrieved from the host product. + */ + +function updateThemeWithAppSkinInfo(appSkinInfo) { + + //Update the background color of the panel + + var panelBackgroundColor = appSkinInfo.panelBackgroundColor.color; + document.body.bgColor = toHex(panelBackgroundColor); + + var styleId = "ppstyle"; + var gradientBg = "background-image: -webkit-linear-gradient(top, " + toHex(panelBackgroundColor, 40) + " , " + toHex(panelBackgroundColor, 10) + ");"; + var gradientDisabledBg = "background-image: -webkit-linear-gradient(top, " + toHex(panelBackgroundColor, 15) + " , " + toHex(panelBackgroundColor, 5) + ");"; + var boxShadow = "-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);"; + var boxActiveShadow = "-webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);"; + + var isPanelThemeLight = panelBackgroundColor.red > 50; // choose your own sweet spot + + var fontColor, disabledFontColor; + var borderColor; + var inputBackgroundColor; + var gradientHighlightBg; + + if(isPanelThemeLight) { + fontColor = "#000000;"; + disabledFontColor = "color:" + toHex(panelBackgroundColor, -70) + ";"; + borderColor = "border-color: " + toHex(panelBackgroundColor, -90) + ";"; + inputBackgroundColor = toHex(panelBackgroundColor, 54) + ";"; + gradientHighlightBg = "background-image: -webkit-linear-gradient(top, " + toHex(panelBackgroundColor, -40) + " , " + toHex(panelBackgroundColor,-50) + ");"; + } else { + fontColor = "#ffffff;"; + disabledFontColor = "color:" + toHex(panelBackgroundColor, 100) + ";"; + borderColor = "border-color: " + toHex(panelBackgroundColor, -45) + ";"; + inputBackgroundColor = toHex(panelBackgroundColor, -20) + ";"; + gradientHighlightBg = "background-image: -webkit-linear-gradient(top, " + toHex(panelBackgroundColor, -20) + " , " + toHex(panelBackgroundColor, -30) + ");"; + } + + //Update the default text style with pp values + + addRule(styleId, ".default", "font-size:" + appSkinInfo.baseFontSize + "px" + "; color:" + fontColor + "; background-color:" + toHex(panelBackgroundColor) + ";"); + addRule(styleId, "button, select, input[type=text], input[type=button], input[type=submit]", borderColor); + addRule(styleId, "p", "color:" + fontColor + ";"); + addRule(styleId, "button", "font-family: " + appSkinInfo.baseFontFamily + ", Arial, sans-serif;"); + addRule(styleId, "button", "color:" + fontColor + ";"); + addRule(styleId, "button", "font-size:" + (1.2 * appSkinInfo.baseFontSize) + "px;"); + addRule(styleId, "button, select, input[type=button], input[type=submit]", gradientBg); + addRule(styleId, "button, select, input[type=button], input[type=submit]", boxShadow); + addRule(styleId, "button:enabled:active, input[type=button]:enabled:active, input[type=submit]:enabled:active", gradientHighlightBg); + addRule(styleId, "button:enabled:active, input[type=button]:enabled:active, input[type=submit]:enabled:active", boxActiveShadow); + addRule(styleId, "[disabled]", gradientDisabledBg); + addRule(styleId, "[disabled]", disabledFontColor); + addRule(styleId, "input[type=text]", "padding:1px 3px;"); + addRule(styleId, "input[type=text]", "background-color: " + inputBackgroundColor + ";"); + addRule(styleId, "input[type=text]:focus", "background-color: #ffffff;"); + addRule(styleId, "input[type=text]:focus", "color: #000000;"); +} + +function addRule(stylesheetId, selector, rule) { + var stylesheet = document.getElementById(stylesheetId); + + if (stylesheet) { + stylesheet = stylesheet.sheet; + if( stylesheet.addRule ){ + stylesheet.addRule(selector, rule); + } else if( stylesheet.insertRule ){ + stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length); + } + } +} + +function reverseColor(color, delta) { + return toHex({red:Math.abs(255-color.red), green:Math.abs(255-color.green), blue:Math.abs(255-color.blue)}, delta); +} + +/** + * Convert the Color object to string in hexadecimal format; + */ + +function toHex(color, delta) { + function computeValue(value, delta) { + var computedValue = !isNaN(delta) ? value + delta : value; + if (computedValue < 0) { + computedValue = 0; + } else if (computedValue > 255) { + computedValue = 255; + } + + computedValue = Math.round(computedValue).toString(16); + return computedValue.length == 1 ? "0" + computedValue : computedValue; + } + + var hex = ""; + if (color) { + hex = computeValue(color.red, delta) + computeValue(color.green, delta) + computeValue(color.blue, delta); + } + return "#" + hex; +} + +function onAppThemeColorChanged(event) { + // Should get a latest HostEnvironment object from application. + var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo; + // Gets the style information such as color info from the skinInfo, + // and redraw all UI controls of your extension according to the style info. + updateThemeWithAppSkinInfo(skinInfo); +} + +/** +* Load JSX file into the scripting context of the product. All the jsx files in +* folder [ExtensionRoot]/jsx & [ExtensionRoot]/jsx/[AppName] will be loaded. +*/ +function loadJSX() { + var csInterface = new CSInterface(); + + // get the appName of the currently used app. For Premiere Pro it's "PPRO" + var appName = csInterface.hostEnvironment.appName; + var extensionPath = csInterface.getSystemPath(SystemPath.EXTENSION); + + // load general JSX script independent of appName + var extensionRootGeneral = extensionPath + '/jsx/'; + csInterface.evalScript('$._ext.evalFiles("' + extensionRootGeneral + '")'); + + // load JSX scripts based on appName + var extensionRootApp = extensionPath + '/jsx/' + appName + '/'; + csInterface.evalScript('$._ext.evalFiles("' + extensionRootApp + '")'); +} + +function evalScript(script, callback) { + new CSInterface().evalScript(script, callback); +} + +function onClickButton(ppid) { + var extScript = "$._ext_" + ppid + ".run()"; + evalScript(extScript); +} diff --git a/pype/premiere/extensions/pype_avalon/index.html b/pype/premiere/extensions/com.pype.avalon/index.html similarity index 100% rename from pype/premiere/extensions/pype_avalon/index.html rename to pype/premiere/extensions/com.pype.avalon/index.html diff --git a/pype/premiere/extensions/pype_avalon/jsx/PPRO/PPro_API_Constants.jsx b/pype/premiere/extensions/com.pype.avalon/jsx/PPRO/PPro_API_Constants.jsx similarity index 100% rename from pype/premiere/extensions/pype_avalon/jsx/PPRO/PPro_API_Constants.jsx rename to pype/premiere/extensions/com.pype.avalon/jsx/PPRO/PPro_API_Constants.jsx diff --git a/pype/premiere/extensions/pype_avalon/jsx/PPRO/Premiere.jsx b/pype/premiere/extensions/com.pype.avalon/jsx/PPRO/Premiere.jsx similarity index 94% rename from pype/premiere/extensions/pype_avalon/jsx/PPRO/Premiere.jsx rename to pype/premiere/extensions/com.pype.avalon/jsx/PPRO/Premiere.jsx index 3003aaf4b8..26ec9d771a 100644 --- a/pype/premiere/extensions/pype_avalon/jsx/PPRO/Premiere.jsx +++ b/pype/premiere/extensions/com.pype.avalon/jsx/PPRO/Premiere.jsx @@ -9,7 +9,7 @@ * accordance with the terms of the Adobe license agreement accompanying * it. If you have received this file from a source other than Adobe, * then your use, modification, or distribution of it requires the prior -* written permission of Adobe. +* written permission of Adobe. **************************************************************************/ #include "PPro_API_Constants.jsx" @@ -47,7 +47,7 @@ $._PPP_={ }, keepPanelLoaded : function() { - app.setExtensionPersistent("com.adobe.PProPanel", 0); // 0, while testing (to enable rapid reload); 1 for "Never unload me, even when not visible." + app.setExtensionPersistent("com.pype.avalon", 0); // 0, while testing (to enable rapid reload); 1 for "Never unload me, even when not visible." }, updateGrowingFile : function() { @@ -104,17 +104,17 @@ $._PPP_={ return "No active sequence."; } }, - + projectPanelSelectionChanged : function(projectItems, viewID) { - + var remainingArgs = projectItems.length; var message = ""; if (remainingArgs){ var message = remainingArgs + " items selected: "; var view = viewID; - - // Concatenate selected project item names, into message. + + // Concatenate selected project item names, into message. for (var i = 0; i < projectItems.length; i++) { message += projectItems[i].name; remainingArgs--; @@ -123,7 +123,7 @@ $._PPP_={ } if (remainingArgs === 1){ message += ", and "; - } + } if (remainingArgs === 0) { message += "."; } @@ -166,8 +166,8 @@ $._PPP_={ if (Folder.fs === 'Windows'){ filterString = "XML files:*.xml"; } - var fileToOpen = File.openDialog ( "Choose Project panel layout to open.", - filterString, + var fileToOpen = File.openDialog ( "Choose Project panel layout to open.", + filterString, false); if (fileToOpen) { if (fileToOpen.fsName.indexOf('.xml')){ // We should really be more careful, but hey, it says it's XML! @@ -177,33 +177,33 @@ $._PPP_={ if (fileContents){ var setResult = app.project.setProjectPanelMetadata(fileContents); if (setResult){ - $._PPP_.updateEventPanel("Could not update layout using " + fileToOpen.filename + "."); + $._PPP_.updateEventPanel("Could not update layout using " + fileToOpen.filename + "."); } else { - $._PPP_.updateEventPanel("Updated layout from .xml file."); + $._PPP_.updateEventPanel("Updated layout from .xml file."); } } } } else { - $._PPP_.updateEventPanel("No valid layout file chosen."); + $._PPP_.updateEventPanel("No valid layout file chosen."); } }, exportSequenceAsPrProj : function() { var activeSequence = app.project.activeSequence; if (activeSequence) { - var startTimeOffset = activeSequence.zeroPoint; + var startTimeOffset = activeSequence.zeroPoint; var prProjExtension = '.prproj'; var outputName = activeSequence.name; var outFolder = Folder.selectDialog(); - + if (outFolder) { - var completeOutputPath = outFolder.fsName + + var completeOutputPath = outFolder.fsName + $._PPP_.getSep() + outputName + prProjExtension; - + app.project.activeSequence.exportAsProject(completeOutputPath); - + $._PPP_.updateEventPanel("Exported " + app.project.activeSequence.name + " to " +completeOutputPath + "."); } else { $._PPP_.updateEventPanel("Could not find or create output folder."); @@ -217,7 +217,7 @@ $._PPP_={ // seqIDsToBeImported[N] = IDN; // //app.project.importSequences(pathToPrProj, seqIDsToBeImported); - + }else { $._PPP_.updateEventPanel("No active sequence."); } @@ -226,13 +226,13 @@ $._PPP_={ createSequenceMarkers : function() { var activeSequence = app.project.activeSequence; if (activeSequence) { - var markers = activeSequence.markers; + var markers = activeSequence.markers; if (markers) { var numMarkers = markers.numMarkers; if (numMarkers > 0) { var marker_index = 1; for(var current_marker = markers.getFirstMarker(); - current_marker !== undefined; + current_marker !== undefined; current_marker = markers.getNextMarker(current_marker)){ if (current_marker.name !== "") { $._PPP_.updateEventPanel( 'Marker ' + marker_index + ' name = ' + current_marker.name + '.'); @@ -250,7 +250,7 @@ $._PPP_={ } } } - + var newCommentMarker = markers.createMarker(12.345); newCommentMarker.name = 'Marker created by PProPanel.'; newCommentMarker.comments = 'Here are some comments, inserted by PProPanel.'; @@ -265,7 +265,7 @@ $._PPP_={ $._PPP_.updateEventPanel("No active sequence."); } }, - + exportFCPXML : function() { if (app.project.activeSequence) { var projPath = new File(app.project.path); @@ -273,14 +273,14 @@ $._PPP_={ var outputName = app.project.activeSequence.name; var xmlExtension = '.xml'; var outputPath = Folder.selectDialog("Choose the output directory"); - + if (outputPath) { var completeOutputPath = outputPath.fsName + $._PPP_.getSep() + outputName + xmlExtension; app.project.activeSequence.exportAsFinalCutProXML(completeOutputPath, 1); // 1 == suppress UI - var info = "Exported FCP XML for " + - app.project.activeSequence.name + - " to " + - completeOutputPath + + var info = "Exported FCP XML for " + + app.project.activeSequence.name + + " to " + + completeOutputPath + "."; $._PPP_.updateEventPanel(info); } else { @@ -296,17 +296,17 @@ $._PPP_={ if (Folder.fs === 'Windows'){ filterString = "All files:*.*"; } - var fileToOpen = File.openDialog ( "Choose file to open.", - filterString, + var fileToOpen = File.openDialog ( "Choose file to open.", + filterString, false); if (fileToOpen) { app.sourceMonitor.openFilePath(fileToOpen.fsName); app.sourceMonitor.play(1.73); // playback speed as float, 1.0 = normal speed forward var position = app.sourceMonitor.getPosition(); // new in 13.0 - $._PPP_.updateEventPanel("Current Source monitor position: " + position.seconds + " seconds."); - fileToOpen.close(); + $._PPP_.updateEventPanel("Current Source monitor position: " + position.seconds + " seconds."); + fileToOpen.close(); } else { - $._PPP_.updateEventPanel("No file chosen."); + $._PPP_.updateEventPanel("No file chosen."); } }, @@ -335,7 +335,7 @@ $._PPP_={ } if (app.project) { var fileOrFilesToImport = File.openDialog ( "Choose files to import", // title - filterString, // filter available files? + filterString, // filter available files? true); // allow multiple? if (fileOrFilesToImport) { // We have an array of File objects; importFiles() takes an array of paths. @@ -344,14 +344,14 @@ $._PPP_={ for (var i = 0; i < fileOrFilesToImport.length; i++) { importThese[i] = fileOrFilesToImport[i].fsName; } - app.project.importFiles(importThese, - 1, // suppress warnings + app.project.importFiles(importThese, + 1, // suppress warnings app.project.getInsertionBin(), 0); // import as numbered stills } } else { $._PPP_.updateEventPanel("No files to import."); - } + } } }, @@ -371,12 +371,12 @@ $._PPP_={ disableImportWorkspaceWithProjects : function() { var prefToModify = 'FE.Prefs.ImportWorkspace'; var appProperties = app.properties; - + if (appProperties){ var propertyExists = app.properties.doesPropertyExist(prefToModify); var propertyIsReadOnly = app.properties.isPropertyReadOnly(prefToModify); var propertyValue = app.properties.getProperty(prefToModify); - + appProperties.setProperty(prefToModify, false, 1); // optional 3rd param : 0 = non-persistent, 1 = persistent (default) var safetyCheck = app.properties.getProperty(prefToModify); if (safetyCheck != propertyValue){ @@ -394,7 +394,7 @@ $._PPP_={ var propertyExists = app.properties.doesPropertyExist(prefToModify); var propertyIsReadOnly = app.properties.isPropertyReadOnly(prefToModify); var originalValue = app.properties.getProperty(prefToModify); - + appProperties.setProperty(prefToModify, false, 1, 1); // optional 4th param : 0 = non-persistent, 1 = persistent (default) var safetyCheck = app.properties.getProperty(prefToModify); if (safetyCheck != originalValue){ @@ -408,22 +408,22 @@ $._PPP_={ }, replaceMedia : function() { - + // Note: This method of changing paths for projectItems is from the time - // before PPro supported full-res AND proxy paths for each projectItem. + // before PPro supported full-res AND proxy paths for each projectItem. // This can still be used, and will change the hi-res projectItem path, but // if your panel supports proxy workflows, it should rely instead upon - // projectItem.setProxyPath() instead. + // projectItem.setProxyPath() instead. - var firstProjectItem = app.project.rootItem.children[0]; + var firstProjectItem = app.project.rootItem.children[0]; if (firstProjectItem) { if (firstProjectItem.canChangeMediaPath()) { + + // NEW in 9.0: setScaleToFrameSize() ensures that for all clips created from this footage, + // auto scale to frame size will be ON, regardless of the current user preference. + // This is important for proxy workflows, to avoid mis-scaling upon replacement. - // NEW in 9.0: setScaleToFrameSize() ensures that for all clips created from this footage, - // auto scale to frame size will be ON, regardless of the current user preference. - // This is important for proxy workflows, to avoid mis-scaling upon replacement. - - // Addendum: This setting will be in effect the NEXT time the projectItem is added to a + // Addendum: This setting will be in effect the NEXT time the projectItem is added to a // sequence; it will not affect or reinterpret clips from this projectItem, already in // sequences. @@ -432,17 +432,17 @@ $._PPP_={ if (Folder.fs === 'Windows'){ filterString = "All files:*.*"; } - var replacementMedia = File.openDialog( "Choose new media file, for " + - firstProjectItem.name, + var replacementMedia = File.openDialog( "Choose new media file, for " + + firstProjectItem.name, filterString, // file filter false); // allow multiple? - + if (replacementMedia) { var suppressWarnings = true; firstProjectItem.name = replacementMedia.name + ", formerly known as " + firstProjectItem.name; firstProjectItem.changeMediaPath(replacementMedia.fsName, suppressWarnings); // new in 12.1 - replacementMedia.close(); - } + replacementMedia.close(); + } } else { $._PPP_.updateEventPanel("Couldn't change path of " + firstProjectItem.name + "."); } @@ -450,14 +450,14 @@ $._PPP_={ $._PPP_.updateEventPanel("No project items found."); } }, - + openProject : function() { var filterString = ""; if (Folder.fs === 'Windows'){ filterString = "Premiere Pro project files:*.prproj"; } - var projToOpen = File.openDialog ( "Choose project:", - filterString, + var projToOpen = File.openDialog ( "Choose project:", + filterString, false); if ((projToOpen) && projToOpen.exists) { app.openDocument( projToOpen.fsName, @@ -465,21 +465,21 @@ $._PPP_={ 1, // suppress 'Locate Files' dialogs? 1); // suppress warning dialogs? projToOpen.close(); - } + } }, exportFramesForMarkers : function (){ app.enableQE(); var activeSequence = app.project.activeSequence; if (activeSequence) { - var markers = activeSequence.markers; + var markers = activeSequence.markers; var markerCount = markers.numMarkers; if (markerCount){ var firstMarker = markers.getFirstMarker(); activeSequence.setPlayerPosition(firstMarker.start.ticks); $._PPP_.exportCurrentFrameAsPNG(); - var previousMarker = 0; + var previousMarker = 0; if (firstMarker){ for(var i = 0; i < markerCount; i++){ if (i === 0){ @@ -517,7 +517,7 @@ $._PPP_={ }, transcode : function(outputPresetPath) { - app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete); + app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete); app.encoder.bind('onEncoderJobError', $._PPP_.onEncoderJobError); app.encoder.bind('onEncoderJobProgress', $._PPP_.onEncoderJobProgress); app.encoder.bind('onEncoderJobQueued', $._PPP_.onEncoderJobQueued); @@ -530,7 +530,7 @@ $._PPP_={ if (firstProjectItem){ app.encoder.launchEncoder(); // This can take a while; let's get the ball rolling. - + var fileOutputPath = Folder.selectDialog("Choose the output directory"); if (fileOutputPath){ var outputName = firstProjectItem.name.search('[.]'); @@ -542,11 +542,11 @@ $._PPP_={ var completeOutputPath = fileOutputPath.fsName + $._PPP_.getSep() + outFileName + '.mxf'; var removeFromQueue = true; var rangeToEncode = app.encoder.ENCODE_IN_TO_OUT; - app.encoder.encodeProjectItem( firstProjectItem, - completeOutputPath, - outputPresetPath, - rangeToEncode, - removeFromQueue); + app.encoder.encodeProjectItem( firstProjectItem, + completeOutputPath, + outputPresetPath, + rangeToEncode, + removeFromQueue); app.encoder.startBatch(); } } else { @@ -563,8 +563,8 @@ $._PPP_={ if (Folder.fs === 'Windows'){ filterString = "All files:*.*"; } - var fileToTranscode = File.openDialog ( "Choose file to open.", - filterString, + var fileToTranscode = File.openDialog ( "Choose file to open.", + filterString, false); if (fileToTranscode) { var fileOutputPath = Folder.selectDialog("Choose the output directory"); @@ -574,11 +574,11 @@ $._PPP_={ var srcOutPoint = 3.0; // encode stop time at 3s (optional--if omitted, encode entire file) var removeFromQueue = false; - var result = app.encoder.encodeFile(fileToTranscode.fsName, - fileOutputPath.fsName, - outputPresetPath, - removeFromQueue, - srcInPoint, + var result = app.encoder.encodeFile(fileToTranscode.fsName, + fileOutputPath.fsName, + outputPresetPath, + removeFromQueue, + srcInPoint, srcOutPoint); } } @@ -590,8 +590,8 @@ $._PPP_={ if (activeSequence) { app.encoder.launchEncoder(); // This can take a while; let's get the ball rolling. - var timeSecs = activeSequence.CTI.secs; // Just for reference, here's how to access the CTI - var timeFrames = activeSequence.CTI.frames; // (Current Time Indicator), for the active sequence. + var timeSecs = activeSequence.CTI.secs; // Just for reference, here's how to access the CTI + var timeFrames = activeSequence.CTI.frames; // (Current Time Indicator), for the active sequence. var timeTicks = activeSequence.CTI.ticks; var timeString = activeSequence.CTI.timecode; @@ -600,7 +600,7 @@ $._PPP_={ var seqInPointAsTime = app.project.activeSequence.getInPointAsTime(); // new in 12.0 var seqOutPointAsTime = app.project.activeSequence.getOutPointAsTime(); // new in 12.0 - + var projPath = new File(app.project.path); var outputPath = Folder.selectDialog("Choose the output directory"); @@ -611,11 +611,11 @@ $._PPP_={ if (outputFormatExtension){ var outputFilename = activeSequence.name + '.' + outputFormatExtension; - var fullPathToFile = outputPath.fsName + - $._PPP_.getSep() + - activeSequence.name + - "." + - outputFormatExtension; + var fullPathToFile = outputPath.fsName + + $._PPP_.getSep() + + activeSequence.name + + "." + + outputFormatExtension; var outFileTest = new File(fullPathToFile); @@ -639,28 +639,28 @@ $._PPP_={ app.encoder.setSidecarXMPEnabled(0); app.encoder.setEmbeddedXMPEnabled(0); - /* + /* For reference, here's how to export from within PPro (blocking further user interaction). - - var seq = app.project.activeSequence; - + + var seq = app.project.activeSequence; + if (seq) { - seq.exportAsMediaDirect(fullPathToFile, - outPreset.fsName, + seq.exportAsMediaDirect(fullPathToFile, + outPreset.fsName, app.encoder.ENCODE_WORKAREA); Bonus: Here's how to compute a sequence's duration, in ticks. 254016000000 ticks/second. - var sequenceDuration = app.project.activeSequence.end - app.project.activeSequence.zeroPoint; + var sequenceDuration = app.project.activeSequence.end - app.project.activeSequence.zeroPoint; } - + */ - + var jobID = app.encoder.encodeSequence( app.project.activeSequence, fullPathToFile, outPreset.fsName, - app.encoder.ENCODE_WORKAREA, - 1); // Remove from queue upon successful completion? + app.encoder.ENCODE_WORKAREA, + 1); // Remove from queue upon successful completion? $._PPP_.updateEventPanel('jobID = ' + jobID); outPreset.close(); } @@ -686,19 +686,19 @@ $._PPP_={ var outputName = String(app.project.name); var array = outputName.split('.', 2); - outputName = array[0]+ sessionCounter + '.' + array[1]; + outputName = array[0]+ sessionCounter + '.' + array[1]; sessionCounter++; var fullOutPath = absPath + $._PPP_.getSep() + outputName; app.project.saveAs(fullOutPath); - for (var a = 0; a < app.projects.numProjects; a++){ - var currentProject = app.projects[a]; - if (currentProject.path === fullOutPath){ + for (var a = 0; a < app.projects.numProjects; a++){ + var currentProject = app.projects[a]; + if (currentProject.path === fullOutPath){ app.openDocument(originalPath); // Why first? So we don't frighten the user by making PPro's window disappear. :) - currentProject.closeDocument(); - } + currentProject.closeDocument(); + } } } else { $._PPP_.updateEventPanel("No output path chosen."); @@ -709,10 +709,10 @@ $._PPP_={ var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. if (projectItem) { if (ExternalObject.AdobeXMPScript === undefined) { - ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); + ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); } if (ExternalObject.AdobeXMPScript !== undefined) { // safety-conscious! - + var xmpBlob = projectItem.getXMPMetadata(); var xmp = new XMPMeta(xmpBlob); var oldSceneVal = ""; @@ -722,13 +722,13 @@ $._PPP_={ var myScene = xmp.getProperty(XMPConst.NS_DM, "scene"); oldSceneVal = myScene.value; } - + if (xmp.doesPropertyExist(XMPConst.NS_DM, "creator") === true){ var myCreator = xmp.getProperty(XMPConst.NS_DM, "creator"); oldCreatorVal = myCreator.value; } - // Regardless of whether there WAS scene or creator data, set scene and creator data. + // Regardless of whether there WAS scene or creator data, set scene and creator data. xmp.setProperty(XMPConst.NS_DM, "scene", oldSceneVal + " Added by PProPanel sample!"); xmp.setProperty(XMPConst.NS_DM, "creator", oldDMCreatorVal + " Added by PProPanel sample!"); @@ -753,15 +753,15 @@ $._PPP_={ xmp.appendArrayItem(XMPConst.NS_DC, // If no values exist, appendArrayItem will create a value. creatorProp, numCreatorValuesPresent + " creator values were already present.", - null, + null, XMPConst.ARRAY_IS_ORDERED); } else { - - xmp.appendArrayItem(XMPConst.NS_DC, + + xmp.appendArrayItem(XMPConst.NS_DC, creatorProp, "PProPanel wrote the first value into NS_DC creator field.", - null, + null, XMPConst.ARRAY_IS_ORDERED); } var xmpAsString = xmp.serialize(); // either way, serialize and write XMP. @@ -771,7 +771,7 @@ $._PPP_={ $._PPP_.updateEventPanel("Project item required."); } }, - + getProductionByName : function(nameToGet) { var production; for (var i = 0; i < productionList.numProductions; i++) { @@ -834,14 +834,14 @@ $._PPP_={ var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. if (projectItem) { if (projectItem.type == ProjectItemType.CLIP || projectItem.type == ProjectItemType.FILE) { - + markers = projectItem.getMarkers(); if (markers) { var num_markers = markers.numMarkers; var new_marker = markers.createMarker(12.345); var guid = new_marker.guid; // new in 11.1 - + new_marker.name = 'Marker created by PProPanel.'; new_marker.comments = 'Here are some comments, inserted by PProPanel.'; new_marker.end = 15.6789; @@ -897,7 +897,7 @@ $._PPP_={ var oldLogValue = ""; var appendThis = "This log note inserted by PProPanel."; var appendTextWasActuallyNew = false; - + if(foundLogNote){ var oldLogNote = xmp.getProperty(kPProPrivateProjectMetadataURI, logNote); if (oldLogNote){ @@ -948,7 +948,7 @@ $._PPP_={ }, updatePAR : function() { - var item = app.project.rootItem.children[0]; + var item = app.project.rootItem.children[0]; if (item) { if ((item.type == ProjectItemType.FILE) || (item.type == ProjectItemType.CLIP)){ // If there is an item, and it's either a clip or file... @@ -960,7 +960,7 @@ $._PPP_={ $._PPP_.updateEventPanel("No project items found."); } }, - + getnumAEProjectItems : function() { var bt = new BridgeTalk(); bt.target = 'aftereffects'; @@ -1016,7 +1016,7 @@ $._PPP_={ var outFile = new File(completeOutputPath); var isThisASequence = projectItem.isSequence(); - + if (outFile){ outFile.encoding = "UTF8"; outFile.open("w", "TEXT", "????"); @@ -1038,10 +1038,10 @@ $._PPP_={ if (projectItem) { if ((projectItem.type == ProjectItemType.CLIP) || (projectItem.type == ProjectItemType.FILE)) { var newSubClipName = prompt('Name of subclip?', projectItem.name + '_' + sessionCounter, 'Name your subclip'); - - var newSubClip = projectItem.createSubClip(newSubClipName, - startTime, - endTime, + + var newSubClip = projectItem.createSubClip(newSubClipName, + startTime, + endTime, hasHardBoundaries, takeVideo, takeAudio); @@ -1086,7 +1086,7 @@ $._PPP_={ var absPath = outputPath.fsName; var outputName = String(app.project.name); var array = outputName.split('.', 2); - outputName = array[0]+ sessionCounter + '.' + array[1]; + outputName = array[0]+ sessionCounter + '.' + array[1]; sessionCounter++; var fullOutPath = absPath + $._PPP_.getSep() + outputName + '.aaf'; @@ -1098,9 +1098,9 @@ $._PPP_={ 0, // explode to mono? 96000, // sample rate 16, // bits per sample - 0, // embed audio? + 0, // embed audio? 0, // audio file format? 0 = aiff, 1 = wav - 0, // trim sources? + 0, // trim sources? 0/*, // number of 'handle' frames optionalPathToOutputPreset*/); // optional; .epr file to use } else { @@ -1147,7 +1147,7 @@ $._PPP_={ }, setProxiesON : function () { - var firstProjectItem = app.project.rootItem.children[0]; + var firstProjectItem = app.project.rootItem.children[0]; if (firstProjectItem) { if (firstProjectItem.canProxy()){ var shouldAttachProxy = true; @@ -1159,8 +1159,8 @@ $._PPP_={ if (Folder.fs === 'Windows'){ filterString = "All files:*.*"; } - var proxyPath = File.openDialog( "Choose proxy for " + firstProjectItem.name + ":", - filterString, + var proxyPath = File.openDialog( "Choose proxy for " + firstProjectItem.name + ":", + filterString, false); if (proxyPath.exists){ firstProjectItem.attachProxy(proxyPath.fsName, 0); @@ -1188,7 +1188,7 @@ $._PPP_={ qe.project.deletePreviewFiles(MediaType.ANY); $._PPP_.updateEventPanel("All video and audio preview files deleted."); }, - + randomizeSequenceSelection : function (){ var sequence = app.project.activeSequence; @@ -1208,7 +1208,7 @@ $._PPP_={ var beforeSelected; var afterSelected; - $._PPP_.updateEventPanel("track : " + ti + " clip count: " + clips.numTracks + " transition count: " + transitions.numTracks); + $._PPP_.updateEventPanel("track : " + ti + " clip count: " + clips.numTracks + " transition count: " + transitions.numTracks); for(var ci=0; ci " + afterSelected); + $._PPP_.updateEventPanel("clip : " + ci + " " + name + " " + beforeSelected + " -> " + afterSelected); } for(var tni=0; tni 0.5), updateUI); - beforeSelected = before ? "Y" : "N"; + beforeSelected = before ? "Y" : "N"; afterSelected = transition.selected ? "Y" : "N"; $._PPP_.updateEventPanel('transition: ' + tni + " " + beforeSelected + " -> " + afterSelected); } } - } + } } else { $._PPP_.updateEventPanel("no active sequence."); } }, // Define a couple of callback functions, for AME to use during render. - + onEncoderJobComplete : function (jobID, outputFilePath) { var eoName; if (Folder.fs == 'Macintosh') { - eoName = "PlugPlugExternalObject"; + eoName = "PlugPlugExternalObject"; } else { eoName = "PlugPlugExternalObject.dll"; } - + var suffixAddedByPPro = '_1'; // You should really test for any suffix. var withoutExtension = outputFilePath.slice(0,-4); // trusting 3 char extension var lastIndex = outputFilePath.lastIndexOf("."); @@ -1273,7 +1273,7 @@ $._PPP_={ if (outputFilePath.indexOf(suffixAddedByPPro)){ $._PPP_.updateEventPanel(" Output filename was changed: the output preset name may have been added, or there may have been an existing file with that name. This would be a good place to deal with such occurrences."); } - + var mylib = new ExternalObject('lib:' + eoName); var eventObj = new CSXSEvent(); @@ -1284,14 +1284,14 @@ $._PPP_={ }, onEncoderJobError : function (jobID, errorMessage) { - var eoName; + var eoName; if (Folder.fs === 'Macintosh') { - eoName = "PlugPlugExternalObject"; + eoName = "PlugPlugExternalObject"; } else { eoName = "PlugPlugExternalObject.dll"; } - + var mylib = new ExternalObject('lib:' + eoName); var eventObj = new CSXSEvent(); @@ -1299,7 +1299,7 @@ $._PPP_={ eventObj.data = "Job " + jobID + " failed, due to " + errorMessage + "."; eventObj.dispatch(); }, - + onEncoderJobProgress : function (jobID, progress) { $._PPP_.updateEventPanel('onEncoderJobProgress called. jobID = ' + jobID + '. progress = ' + progress + '.'); }, @@ -1325,12 +1325,12 @@ $._PPP_={ $._PPP_.updateEventPanel('component ' + i + ' = ' + clipComponents[i].matchName + ' : ' + clipComponents[i].displayName); } if (clipComponents.numItems > 2){ - + // 0 = clip // 1 = Opacity // N effects, then... // Shape layer (new in 12.0) - + var blur = clipComponents[2]; // Assume Gaussian Blur is the first effect applied to the clip. if (blur){ var blurProps = blur.properties; @@ -1429,7 +1429,7 @@ $._PPP_={ var wrapper = []; wrapper[0] = outputFilePath; - + var nameToFind = 'Proxies generated by PProPanel'; var targetBin = $._PPP_.getPPPInsertionBin(); if (targetBin){ @@ -1457,7 +1457,7 @@ $._PPP_={ filterString = "All files:*.*"; } var fileOrFilesToImport = File.openDialog( "Choose full resolution files to import", // title - filterString, // filter available files? + filterString, // filter available files? true); // allow multiple? if (fileOrFilesToImport) { var nameToFind = 'Proxies generated by PProPanel'; @@ -1466,7 +1466,7 @@ $._PPP_={ // If panel can't find the target bin, it creates it. app.project.rootItem.createBin(nameToFind); targetBin = $._PPP_.searchForBinWithName(nameToFind); - } + } if (targetBin){ targetBin.select(); var importThese = []; // We have an array of File objects; importFiles() takes an array of paths. @@ -1474,18 +1474,18 @@ $._PPP_={ for (var i = 0; i < fileOrFilesToImport.length; i++) { importThese[i] = fileOrFilesToImport[i].fsName; var justFileName = extractFileNameFromPath(importThese[i]); - var suffix = '_PROXY.mp4'; + var suffix = '_PROXY.mp4'; var containingPath = fileOrFilesToImport[i].parent.fsName; - var completeProxyPath = containingPath + $._PPP_.getSep() + justFileName + suffix; + var completeProxyPath = containingPath + $._PPP_.getSep() + justFileName + suffix; - var jobID = app.encoder.encodeFile(fileOrFilesToImport[i].fsName, - completeProxyPath, - outputPresetPath, + var jobID = app.encoder.encodeFile(fileOrFilesToImport[i].fsName, + completeProxyPath, + outputPresetPath, 0); } - app.project.importFiles(importThese, - 1, // suppress warnings + app.project.importFiles(importThese, + 1, // suppress warnings targetBin, 0); // import as numbered stills } @@ -1509,7 +1509,7 @@ $._PPP_={ var targetVTrack = seq.videoTracks[(numVTracks - 1)]; if (targetVTrack){ // If there are already clips in this track, - // append this one to the end. Otherwise, + // append this one to the end. Otherwise, // insert at start time. if (targetVTrack.clips.numItems > 0){ @@ -1554,7 +1554,7 @@ $._PPP_={ closeFrontSourceClip : function() { app.sourceMonitor.closeClip(); }, - + closeAllClipsInSourceMonitor : function() { app.sourceMonitor.closeAllClips(); }, @@ -1599,17 +1599,17 @@ $._PPP_={ filterString = "All files:*.*"; } compNamesToImport = []; - + var aepToImport = File.openDialog ( "Choose After Effects project", // title - filterString, // filter available files? + filterString, // filter available files? false); // allow multiple? if (aepToImport) { var importAll = confirm("Import all compositions in project?", false, "Import all?"); if (importAll){ var result = app.project.importAllAEComps(aepToImport.fsName, targetBin); } else { - var compName = prompt( 'Name of composition to import?', - '', + var compName = prompt( 'Name of composition to import?', + '', 'Which Comp to import'); if (compName){ compNamesToImport[0] = compName; @@ -1625,7 +1625,7 @@ $._PPP_={ $._PPP_.updateEventPanel("Could not find or create target bin."); } }, - + consolidateProject : function () { var pmo = app.projectManager.options; @@ -1635,7 +1635,7 @@ $._PPP_={ if (Folder.fs === 'Windows'){ filterString = "Output Presets:*.epr"; } - + var outFolder = Folder.selectDialog("Choose output directory."); if (outFolder) { @@ -1643,26 +1643,26 @@ $._PPP_={ var useSpecificPreset = confirm("Would you like to select an output preset?", false, "Are you sure...?"); if (useSpecificPreset){ var useThisEPR = File.openDialog ( "Choose output preset (.epr file)", // title - filterString, // filter available files? + filterString, // filter available files? false); // allow multiple? if (useThisEPR){ - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; pmo.encoderPresetFilePath = useThisEPR.fsName; } } else { - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; } - + var processAllSequences = confirm("Process all sequences? No = just the first sequence found.", true, "Process all?"); - + if (processAllSequences){ pmo.includeAllSequences = true; } else { pmo.includeAllSequences = false; pmo.affectedSequences = [app.project.sequences[0]]; } - + pmo.clipTransferOption = pmo.CLIP_TRANSFER_TRANSCODE; pmo.convertAECompsToClips = false; pmo.convertSyntheticsToClips = false; @@ -1676,7 +1676,7 @@ $._PPP_={ var result = app.projectManager.process(app.project); var errorList = app.projectManager.errors; - + if(errorList.length){ for (var k = 0; k < errorList.length; k++){ $._PPP_.updateEventPanel(errorList[k][1]); @@ -1695,7 +1695,7 @@ $._PPP_={ if (Folder.fs === 'Windows'){ filterString = "Output Presets:*.epr"; } - + var outFolder = Folder.selectDialog("Choose output directory."); if (outFolder) { @@ -1703,26 +1703,26 @@ $._PPP_={ var useSpecificPreset = confirm("Would you like to select an output preset?", false, "Are you sure...?"); if (useSpecificPreset){ var useThisEPR = File.openDialog ( "Choose output preset (.epr file)", // title - filterString, // filter available files? + filterString, // filter available files? false); // allow multiple? if (useThisEPR){ - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; pmo.encoderPresetFilePath = useThisEPR.fsName; } } else { - pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; } - + var processAllSequences = confirm("Process all sequences? No = just the first sequence found.", true, "Process all?"); - + if (processAllSequences){ pmo.includeAllSequences = true; } else { pmo.includeAllSequences = false; pmo.affectedSequences = [app.project.sequences[0]]; } - + pmo.clipTransferOption = pmo.CLIP_TRANSFER_TRANSCODE; pmo.convertAECompsToClips = false; pmo.convertSyntheticsToClips = false; @@ -1736,7 +1736,7 @@ $._PPP_={ var result = app.projectManager.process(app.project); var errorList = app.projectManager.errors; - + if(errorList.length){ for (var k = 0; k < errorList.length; k++){ $._PPP_.updateEventPanel(errorList[k][1]); @@ -1757,14 +1757,14 @@ $._PPP_={ filterString = "Motion Graphics Templates:*.mogrt"; } var mogrtToImport = File.openDialog ( "Choose MoGRT", // title - filterString, // filter available files? + filterString, // filter available files? false); // allow multiple? if (mogrtToImport){ var targetTime = activeSeq.getPlayerPosition(); var vidTrackOffset = 0; var audTrackOffset = 0; - var newTrackItem = activeSeq.importMGT( mogrtToImport.fsName, - targetTime.ticks, + var newTrackItem = activeSeq.importMGT( mogrtToImport.fsName, + targetTime.ticks, vidTrackOffset, audTrackOffset); if (newTrackItem){ @@ -1782,10 +1782,10 @@ $._PPP_={ } } } else { - app.setSDKEventMessage('Unable to import ' + mogrtToImport.fsName + '.', 'error'); + app.setSDKEventMessage('Unable to import ' + mogrtToImport.fsName + '.', 'error'); } } else { - app.setSDKEventMessage('No active sequence.'); + app.setSDKEventMessage('No active sequence.'); } }, @@ -1799,7 +1799,7 @@ $._PPP_={ var viewIDs = app.getProjectViewIDs(); var firstProject = app.getProjectFromViewID(viewIDs[0]); var arrayOfRandomProjectItems = []; - + for (var b = 0; b < app.project.rootItem.children.numItems; b++){ var currentProjectItem = app.project.rootItem.children[b]; if (Math.random() > 0.5){ @@ -1858,13 +1858,13 @@ $._PPP_={ } } }, - + updateFrameRate : function() { - var item = app.project.rootItem.children[0]; + var item = app.project.rootItem.children[0]; if (item) { if ((item.type == ProjectItemType.FILE) || (item.type == ProjectItemType.CLIP)){ // If there is an item, and it's either a clip or file... - item.setOverrideFrameRate(23.976); + item.setOverrideFrameRate(23.976); } else { $._PPP_.updateEventPanel('You cannot override the frame rate of bins or sequences.'); } @@ -1905,12 +1905,12 @@ $._PPP_={ if (projectItem) { if (projectItem.type == ProjectItemType.CLIP || projectItem.type == ProjectItemType.FILE) { - + markers = projectItem.getMarkers(); if (markers) { var markerCount = markers.numMarkers; - + if (markerCount){ for(var thisMarker = markers.getFirstMarker(); thisMarker !== undefined; thisMarker = markers.getNextMarker(thisMarker)){ var oldColor = thisMarker.getColorByIndex(); @@ -1931,7 +1931,7 @@ $._PPP_={ } } else { $._PPP_.updateEventPanel("Project is empty."); - } + } }, changeSeqTimeCodeDisplay : function() { @@ -1963,7 +1963,7 @@ $._PPP_={ if (sel[i].name !== 'anonymous'){ $._PPP_.updateEventPanel('Selected item ' + (i+1) + ' == ' + sel[i].name + '.'); } - } + } }, registerActiveSequenceChangedFxn : function() { @@ -2015,7 +2015,7 @@ $._PPP_={ var thisProj = app.getProjectFromViewID(viewIDs[a]); if (thisProj.documentID !== app.project.documentID){ closeTheseProjects[a] = thisProj; - } + } } // Why do this afterward? Because if we close projects in that loop, we change the active project. :) for (var b = 0; b < closeTheseProjects.length; b++){ @@ -2058,7 +2058,7 @@ $._PPP_={ } if (remainingArgs === 1){ message += ", and "; - } + } if (remainingArgs === 0) { message += "."; } @@ -2092,7 +2092,7 @@ $._PPP_={ var selectedPreset = undefined; var selectedExporter = undefined; var exporters = app.encoder.getExporters(); - + var outFile = new File(outputFileName); outFile.encoding = "UTF8"; @@ -2110,7 +2110,7 @@ $._PPP_={ var preset = presets[j]; if (preset){ outFile.writeln('matchName: ' + preset.matchName + '(' + preset.name+')'); - if (preset.name.indexOf('TQM') > -1){ + if (preset.name.indexOf('TQM') > -1){ selectedPreset = preset; selectedExporter = exporter; outFile.writeln('selected preset = ' + selectedExporter.name + ' : ' + selectedPreset.name); @@ -2185,7 +2185,7 @@ $._PPP_={ var currentItem = selectedItems[b]; if (currentItem){ if ((currentItem.type !== ProjectItemType.BIN) && - (currentItem.isSequence() === false)){ + (currentItem.isSequence() === false)){ var interp = currentItem.getFootageInterpretation(); if (interp) { // Note: I made this something terrible, so the change is apparent. @@ -2197,7 +2197,7 @@ $._PPP_={ } var mapping = currentItem.getAudioChannelMapping; if (mapping){ - mapping.audioChannelsType = AUDIOCHANNELTYPE_Stereo; + mapping.audioChannelsType = AUDIOCHANNELTYPE_Stereo; mapping.audioClipsNumber = 1; mapping.setMappingForChannel(0, 4); // 1st param = channel index, 2nd param = source index mapping.setMappingForChannel(1, 5); @@ -2219,7 +2219,7 @@ $._PPP_={ } else { $._PPP_.updateEventPanel("No view IDs available."); } - }, + }, createSubSequence : function() { @@ -2260,7 +2260,7 @@ $._PPP_={ } else { $._PPP_.updateEventPanel("No active sequence."); } - }, + }, selectAllRetimedClips : function() { var activeSeq = app.project.activeSequence; @@ -2283,7 +2283,7 @@ $._PPP_={ } } } - } + } $._PPP_.updateEventPanel(numRetimedClips + " retimed clips found."); } else { $._PPP_.updateEventPanel("No active sequence."); @@ -2355,7 +2355,7 @@ $._PPP_={ var AMEString = "var fe = app.getFrontend(); fe.stitchFiles(\"" + allPathsToStitch + "\""; var addendum = ", \"H.264\", \"" + presetPath + "\", " + "\"(This path parameter is never used)\");"; - AMEString += addendum; + AMEString += addendum; // 3. Send Command to AME for Export // var bt = new BridgeTalk(); @@ -2364,7 +2364,7 @@ $._PPP_={ bt.send(); - + } } } diff --git a/pype/premiere/extensions/com.pype.avalon/jsx/general.jsx b/pype/premiere/extensions/com.pype.avalon/jsx/general.jsx new file mode 100644 index 0000000000..72abb9f581 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/jsx/general.jsx @@ -0,0 +1,19 @@ +/************************************************************************* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2014 Adobe +* All Rights Reserved. +* +* NOTICE: Adobe permits you to use, modify, and distribute this file in +* accordance with the terms of the Adobe license agreement accompanying +* it. If you have received this file from a source other than Adobe, +* then your use, modification, or distribution of it requires the prior +* written permission of Adobe. +**************************************************************************/ +if (typeof $ == 'undefined') { + $ = {}; +} + +// this file should contain jsx-code that can run in all apps +// like polyfills of e.g. JSON diff --git a/pype/premiere/extensions/pype_avalon/lib/CEPEngine_extensions.js b/pype/premiere/extensions/com.pype.avalon/lib/CEPEngine_extensions.js similarity index 100% rename from pype/premiere/extensions/pype_avalon/lib/CEPEngine_extensions.js rename to pype/premiere/extensions/com.pype.avalon/lib/CEPEngine_extensions.js diff --git a/pype/premiere/extensions/pype_avalon/lib/CSInterface.js b/pype/premiere/extensions/com.pype.avalon/lib/CSInterface.js similarity index 100% rename from pype/premiere/extensions/pype_avalon/lib/CSInterface.js rename to pype/premiere/extensions/com.pype.avalon/lib/CSInterface.js diff --git a/pype/premiere/extensions/pype_avalon/lib/Vulcan.js b/pype/premiere/extensions/com.pype.avalon/lib/Vulcan.js similarity index 100% rename from pype/premiere/extensions/pype_avalon/lib/Vulcan.js rename to pype/premiere/extensions/com.pype.avalon/lib/Vulcan.js diff --git a/pype/premiere/extensions/pype_avalon/lib/jquery-1.9.1.js b/pype/premiere/extensions/com.pype.avalon/lib/jquery-1.9.1.js similarity index 100% rename from pype/premiere/extensions/pype_avalon/lib/jquery-1.9.1.js rename to pype/premiere/extensions/com.pype.avalon/lib/jquery-1.9.1.js diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/glob/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/LICENSE new file mode 100644 index 0000000000..19129e315f --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/glob/README.md b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/README.md new file mode 100644 index 0000000000..baa1d1ba86 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/README.md @@ -0,0 +1,368 @@ +# Glob + +Match files using the patterns the shell uses, like stars and stuff. + +[![Build Status](https://travis-ci.org/isaacs/node-glob.svg?branch=master)](https://travis-ci.org/isaacs/node-glob/) [![Build Status](https://ci.appveyor.com/api/projects/status/kd7f3yftf7unxlsx?svg=true)](https://ci.appveyor.com/project/isaacs/node-glob) [![Coverage Status](https://coveralls.io/repos/isaacs/node-glob/badge.svg?branch=master&service=github)](https://coveralls.io/github/isaacs/node-glob?branch=master) + +This is a glob implementation in JavaScript. It uses the `minimatch` +library to do its matching. + +![](oh-my-glob.gif) + +## Usage + +Install with npm + +``` +npm i glob +``` + +```javascript +var glob = require("glob") + +// options is optional +glob("**/*.js", options, function (er, files) { + // files is an array of filenames. + // If the `nonull` option is set, and nothing + // was found, then files is ["**/*.js"] + // er is an error object or null. +}) +``` + +## Glob Primer + +"Globs" are the patterns you type when you do stuff like `ls *.js` on +the command line, or put `build/*` in a `.gitignore` file. + +Before parsing the path part patterns, braced sections are expanded +into a set. Braced sections start with `{` and end with `}`, with any +number of comma-delimited sections within. Braced sections may contain +slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`. + +The following characters have special magic meaning when used in a +path portion: + +* `*` Matches 0 or more characters in a single path portion +* `?` Matches 1 character +* `[...]` Matches a range of characters, similar to a RegExp range. + If the first character of the range is `!` or `^` then it matches + any character not in the range. +* `!(pattern|pattern|pattern)` Matches anything that does not match + any of the patterns provided. +* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the + patterns provided. +* `+(pattern|pattern|pattern)` Matches one or more occurrences of the + patterns provided. +* `*(a|b|c)` Matches zero or more occurrences of the patterns provided +* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns + provided +* `**` If a "globstar" is alone in a path portion, then it matches + zero or more directories and subdirectories searching for matches. + It does not crawl symlinked directories. + +### Dots + +If a file or directory path portion has a `.` as the first character, +then it will not match any glob pattern unless that pattern's +corresponding path part also has a `.` as its first character. + +For example, the pattern `a/.*/c` would match the file at `a/.b/c`. +However the pattern `a/*/c` would not, because `*` does not start with +a dot character. + +You can make glob treat dots as normal characters by setting +`dot:true` in the options. + +### Basename Matching + +If you set `matchBase:true` in the options, and the pattern has no +slashes in it, then it will seek for any file anywhere in the tree +with a matching basename. For example, `*.js` would match +`test/simple/basic.js`. + +### Empty Sets + +If no matching files are found, then an empty array is returned. This +differs from the shell, where the pattern itself is returned. For +example: + + $ echo a*s*d*f + a*s*d*f + +To get the bash-style behavior, set the `nonull:true` in the options. + +### See Also: + +* `man sh` +* `man bash` (Search for "Pattern Matching") +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob.hasMagic(pattern, [options]) + +Returns `true` if there are any special characters in the pattern, and +`false` otherwise. + +Note that the options affect the results. If `noext:true` is set in +the options object, then `+(a|b)` will not be considered a magic +pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` +then that is considered magical, unless `nobrace:true` is set in the +options. + +## glob(pattern, [options], cb) + +* `pattern` `{String}` Pattern to be matched +* `options` `{Object}` +* `cb` `{Function}` + * `err` `{Error | null}` + * `matches` `{Array}` filenames found matching the pattern + +Perform an asynchronous glob search. + +## glob.sync(pattern, [options]) + +* `pattern` `{String}` Pattern to be matched +* `options` `{Object}` +* return: `{Array}` filenames found matching the pattern + +Perform a synchronous glob search. + +## Class: glob.Glob + +Create a Glob object by instantiating the `glob.Glob` class. + +```javascript +var Glob = require("glob").Glob +var mg = new Glob(pattern, options, cb) +``` + +It's an EventEmitter, and starts walking the filesystem to find matches +immediately. + +### new glob.Glob(pattern, [options], [cb]) + +* `pattern` `{String}` pattern to search for +* `options` `{Object}` +* `cb` `{Function}` Called when an error occurs, or matches are found + * `err` `{Error | null}` + * `matches` `{Array}` filenames found matching the pattern + +Note that if the `sync` flag is set in the options, then matches will +be immediately available on the `g.found` member. + +### Properties + +* `minimatch` The minimatch object that the glob uses. +* `options` The options object passed in. +* `aborted` Boolean which is set to true when calling `abort()`. There + is no way at this time to continue a glob search after aborting, but + you can re-use the statCache to avoid having to duplicate syscalls. +* `cache` Convenience object. Each field has the following possible + values: + * `false` - Path does not exist + * `true` - Path exists + * `'FILE'` - Path exists, and is not a directory + * `'DIR'` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` +* `statCache` Cache of `fs.stat` results, to prevent statting the same + path multiple times. +* `symlinks` A record of which paths are symbolic links, which is + relevant in resolving `**` patterns. +* `realpathCache` An optional object which is passed to `fs.realpath` + to minimize unnecessary syscalls. It is stored on the instantiated + Glob object, and may be re-used. + +### Events + +* `end` When the matching is finished, this is emitted with all the + matches found. If the `nonull` option is set, and no match was found, + then the `matches` list contains the original pattern. The matches + are sorted, unless the `nosort` flag is set. +* `match` Every time a match is found, this is emitted with the specific + thing that matched. It is not deduplicated or resolved to a realpath. +* `error` Emitted when an unexpected error is encountered, or whenever + any fs error occurs if `options.strict` is set. +* `abort` When `abort()` is called, this event is raised. + +### Methods + +* `pause` Temporarily stop the search +* `resume` Resume the search +* `abort` Stop the search forever + +### Options + +All the options that can be passed to Minimatch can also be passed to +Glob to change pattern matching behavior. Also, some have been added, +or have glob-specific ramifications. + +All options are false by default, unless otherwise noted. + +All options are added to the Glob object, as well. + +If you are running many `glob` operations, you can pass a Glob object +as the `options` argument to a subsequent operation to shortcut some +`stat` and `readdir` calls. At the very least, you may pass in shared +`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that +parallel glob operations will be sped up by sharing information about +the filesystem. + +* `cwd` The current working directory in which to search. Defaults + to `process.cwd()`. +* `root` The place where patterns starting with `/` will be mounted + onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix + systems, and `C:\` or some such on Windows.) +* `dot` Include `.dot` files in normal matches and `globstar` matches. + Note that an explicit dot in a portion of the pattern will always + match dot files. +* `nomount` By default, a pattern starting with a forward-slash will be + "mounted" onto the root setting, so that a valid filesystem path is + returned. Set this flag to disable that behavior. +* `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +* `nosort` Don't sort the results. +* `stat` Set to true to stat *all* results. This reduces performance + somewhat, and is completely unnecessary, unless `readdir` is presumed + to be an untrustworthy indicator of file existence. +* `silent` When an unusual error is encountered when attempting to + read a directory, a warning will be printed to stderr. Set the + `silent` option to true to suppress these warnings. +* `strict` When an unusual error is encountered when attempting to + read a directory, the process will just continue on in search of + other matches. Set the `strict` option to raise an error in these + cases. +* `cache` See `cache` property above. Pass in a previously generated + cache object to save some fs calls. +* `statCache` A cache of results of filesystem information, to prevent + unnecessary stat calls. While it should not normally be necessary + to set this, you may pass the statCache from one glob() call to the + options object of another, if you know that the filesystem will not + change between calls. (See "Race Conditions" below.) +* `symlinks` A cache of known symbolic links. You may pass in a + previously generated `symlinks` object to save `lstat` calls when + resolving `**` matches. +* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. +* `nounique` In some cases, brace-expanded patterns can result in the + same file showing up multiple times in the result set. By default, + this implementation prevents duplicates in the result set. Set this + flag to disable that behavior. +* `nonull` Set to never return an empty set, instead returning a set + containing the pattern itself. This is the default in glob(3). +* `debug` Set to enable debug logging in minimatch and glob. +* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. +* `noglobstar` Do not match `**` against multiple filenames. (Ie, + treat it as a normal `*` instead.) +* `noext` Do not match `+(a|b)` "extglob" patterns. +* `nocase` Perform a case-insensitive match. Note: on + case-insensitive filesystems, non-magic patterns will match by + default, since `stat` and `readdir` will not raise errors. +* `matchBase` Perform a basename-only match if the pattern does not + contain any slash characters. That is, `*.js` would be treated as + equivalent to `**/*.js`, matching all js files in all directories. +* `nodir` Do not match directories, only files. (Note: to match + *only* directories, simply put a `/` at the end of the pattern.) +* `ignore` Add a pattern or an array of glob patterns to exclude matches. + Note: `ignore` patterns are *always* in `dot:true` mode, regardless + of any other settings. +* `follow` Follow symlinked directories when expanding `**` patterns. + Note that this can result in a lot of duplicate references in the + presence of cyclic links. +* `realpath` Set to true to call `fs.realpath` on all of the results. + In the case of a symlink that cannot be resolved, the full absolute + path to the matched entry is returned (though it will usually be a + broken symlink) +* `absolute` Set to true to always receive absolute paths for matched + files. Unlike `realpath`, this also affects the values returned in + the `match` event. + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between node-glob and other +implementations, and are intentional. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.3, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +Note that symlinked directories are not crawled as part of a `**`, +though their contents may match against subsequent portions of the +pattern. This prevents infinite loops and duplicates and the like. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +### Comments and Negation + +Previously, this module let you mark a pattern as a "comment" if it +started with a `#` character, or a "negated" pattern if it started +with a `!` character. + +These options were deprecated in version 5, and removed in version 6. + +To specify things that should not match, use the `ignore` option. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will always +be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto the +root setting using `path.join`. On windows, this will by default result +in `/foo/*` matching `C:\foo\bar.txt`. + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race conditions, +since it relies on directory walking and such. + +As a result, it is possible that a file that exists when glob looks for +it may have been deleted or modified by the time it returns the result. + +As part of its internal implementation, this program caches all stat +and readdir calls that it makes, in order to cut down on system +overhead. However, this also makes it even more susceptible to races, +especially if the cache or statCache objects are reused between glob +calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast majority +of operations, this is never a problem. + +## Contributing + +Any change to behavior (including bugfixes) must come with a test. + +Patches that fail tests or reduce performance will be rejected. + +``` +# to run tests +npm test + +# to re-generate test fixtures +npm run test-regen + +# to benchmark against bash/zsh +npm run bench + +# to profile javascript +npm run prof +``` diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/glob/changelog.md b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/changelog.md new file mode 100644 index 0000000000..41636771e3 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/changelog.md @@ -0,0 +1,67 @@ +## 7.0 + +- Raise error if `options.cwd` is specified, and not a directory + +## 6.0 + +- Remove comment and negation pattern support +- Ignore patterns are always in `dot:true` mode + +## 5.0 + +- Deprecate comment and negation patterns +- Fix regression in `mark` and `nodir` options from making all cache + keys absolute path. +- Abort if `fs.readdir` returns an error that's unexpected +- Don't emit `match` events for ignored items +- Treat ENOTSUP like ENOTDIR in readdir + +## 4.5 + +- Add `options.follow` to always follow directory symlinks in globstar +- Add `options.realpath` to call `fs.realpath` on all results +- Always cache based on absolute path + +## 4.4 + +- Add `options.ignore` +- Fix handling of broken symlinks + +## 4.3 + +- Bump minimatch to 2.x +- Pass all tests on Windows + +## 4.2 + +- Add `glob.hasMagic` function +- Add `options.nodir` flag + +## 4.1 + +- Refactor sync and async implementations for performance +- Throw if callback provided to sync glob function +- Treat symbolic links in globstar results the same as Bash 4.3 + +## 4.0 + +- Use `^` for dependency versions (bumped major because this breaks + older npm versions) +- Ensure callbacks are only ever called once +- switch to ISC license + +## 3.x + +- Rewrite in JavaScript +- Add support for setting root, cwd, and windows support +- Cache many fs calls +- Add globstar support +- emit match events + +## 2.x + +- Use `glob.h` and `fnmatch.h` from NetBSD + +## 1.x + +- `glob.h` static binding. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/glob/common.js b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/common.js new file mode 100644 index 0000000000..66651bb3aa --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/common.js @@ -0,0 +1,240 @@ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/glob/glob.js b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/glob.js new file mode 100644 index 0000000000..58dec0f6c2 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/glob.js @@ -0,0 +1,790 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + + if (!pattern) + return false + + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + this._processing = 0 + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = isAbsolute(e) ? e : this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) + e = abs + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/glob/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/package.json new file mode 100644 index 0000000000..99167888c3 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/package.json @@ -0,0 +1,76 @@ +{ + "_from": "glob@^7.0.5", + "_id": "glob@7.1.2", + "_inBundle": false, + "_integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "_location": "/glob", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "glob@^7.0.5", + "name": "glob", + "escapedName": "glob", + "rawSpec": "^7.0.5", + "saveSpec": null, + "fetchSpec": "^7.0.5" + }, + "_requiredBy": [ + "/rimraf" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "_shasum": "c19c9df9a028702d678612384a6552404c636d15", + "_spec": "glob@^7.0.5", + "_where": "/Library/Application Support/Adobe/CEP/extensions/ppro/node_modules/rimraf", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "bundleDependencies": false, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "deprecated": false, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^7.1.2", + "tick": "0.0.6" + }, + "engines": { + "node": "*" + }, + "files": [ + "glob.js", + "sync.js", + "common.js" + ], + "homepage": "https://github.com/isaacs/node-glob#readme", + "license": "ISC", + "main": "glob.js", + "name": "glob", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "bench": "bash benchmark.sh", + "benchclean": "node benchclean.js", + "prepublish": "npm run benchclean", + "prof": "bash prof.sh && cat profile.txt", + "profclean": "rm -f v8.log profile.txt", + "test": "tap test/*.js --cov", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js" + }, + "version": "7.1.2" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/glob/sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/sync.js new file mode 100644 index 0000000000..c952134baa --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/glob/sync.js @@ -0,0 +1,486 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return + + var abs = this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) { + e = abs + } + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } + } + + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/.npmignore b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/.npmignore new file mode 100644 index 0000000000..cefaa67a6a --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/.npmignore @@ -0,0 +1,2 @@ +test/ +.travis.yml \ No newline at end of file diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/CHANGELOG.md b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/CHANGELOG.md new file mode 100644 index 0000000000..66fcbb42dd --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/CHANGELOG.md @@ -0,0 +1,126 @@ +2.4.0 / 2016-09-15 +------------------ +### Changed +- added optional support for `graceful-fs` [#62] + +2.3.1 / 2016-05-13 +------------------ +- fix to support BOM. [#45][#45] + +2.3.0 / 2016-04-16 +------------------ +- add `throws` to `readFile()`. See [#39][#39] +- add support for any arbitrary `fs` module. Useful with [mock-fs](https://www.npmjs.com/package/mock-fs) + +2.2.3 / 2015-10-14 +------------------ +- include file name in parse error. See: https://github.com/jprichardson/node-jsonfile/pull/34 + +2.2.2 / 2015-09-16 +------------------ +- split out tests into separate files +- fixed `throws` when set to `true` in `readFileSync()`. See: https://github.com/jprichardson/node-jsonfile/pull/33 + +2.2.1 / 2015-06-25 +------------------ +- fixed regression when passing in string as encoding for options in `writeFile()` and `writeFileSync()`. See: https://github.com/jprichardson/node-jsonfile/issues/28 + +2.2.0 / 2015-06-25 +------------------ +- added `options.spaces` to `writeFile()` and `writeFileSync()` + +2.1.2 / 2015-06-22 +------------------ +- fixed if passed `readFileSync(file, 'utf8')`. See: https://github.com/jprichardson/node-jsonfile/issues/25 + +2.1.1 / 2015-06-19 +------------------ +- fixed regressions if `null` is passed for options. See: https://github.com/jprichardson/node-jsonfile/issues/24 + +2.1.0 / 2015-06-19 +------------------ +- cleanup: JavaScript Standard Style, rename files, dropped terst for assert +- methods now support JSON revivers/replacers + +2.0.1 / 2015-05-24 +------------------ +- update license attribute https://github.com/jprichardson/node-jsonfile/pull/21 + +2.0.0 / 2014-07-28 +------------------ +* added `\n` to end of file on write. [#14](https://github.com/jprichardson/node-jsonfile/pull/14) +* added `options.throws` to `readFileSync()` +* dropped support for Node v0.8 + +1.2.0 / 2014-06-29 +------------------ +* removed semicolons +* bugfix: passed `options` to `fs.readFile` and `fs.readFileSync`. This technically changes behavior, but +changes it according to docs. [#12][#12] + +1.1.1 / 2013-11-11 +------------------ +* fixed catching of callback bug (ffissore / #5) + +1.1.0 / 2013-10-11 +------------------ +* added `options` param to methods, (seanodell / #4) + +1.0.1 / 2013-09-05 +------------------ +* removed `homepage` field from package.json to remove NPM warning + +1.0.0 / 2013-06-28 +------------------ +* added `.npmignore`, #1 +* changed spacing default from `4` to `2` to follow Node conventions + +0.0.1 / 2012-09-10 +------------------ +* Initial release. + +[#45]: https://github.com/jprichardson/node-jsonfile/issues/45 "Reading of UTF8-encoded (w/ BOM) files fails" +[#44]: https://github.com/jprichardson/node-jsonfile/issues/44 "Extra characters in written file" +[#43]: https://github.com/jprichardson/node-jsonfile/issues/43 "Prettyfy json when written to file" +[#42]: https://github.com/jprichardson/node-jsonfile/pull/42 "Moved fs.readFileSync within the try/catch" +[#41]: https://github.com/jprichardson/node-jsonfile/issues/41 "Linux: Hidden file not working" +[#40]: https://github.com/jprichardson/node-jsonfile/issues/40 "autocreate folder doesnt work from Path-value" +[#39]: https://github.com/jprichardson/node-jsonfile/pull/39 "Add `throws` option for readFile (async)" +[#38]: https://github.com/jprichardson/node-jsonfile/pull/38 "Update README.md writeFile[Sync] signature" +[#37]: https://github.com/jprichardson/node-jsonfile/pull/37 "support append file" +[#36]: https://github.com/jprichardson/node-jsonfile/pull/36 "Add typescript definition file." +[#35]: https://github.com/jprichardson/node-jsonfile/pull/35 "Add typescript definition file." +[#34]: https://github.com/jprichardson/node-jsonfile/pull/34 "readFile JSON parse error includes filename" +[#33]: https://github.com/jprichardson/node-jsonfile/pull/33 "fix throw->throws typo in readFileSync()" +[#32]: https://github.com/jprichardson/node-jsonfile/issues/32 "readFile & readFileSync can possible have strip-comments as an option?" +[#31]: https://github.com/jprichardson/node-jsonfile/pull/31 "[Modify] Support string include is unicode escape string" +[#30]: https://github.com/jprichardson/node-jsonfile/issues/30 "How to use Jsonfile package in Meteor.js App?" +[#29]: https://github.com/jprichardson/node-jsonfile/issues/29 "writefile callback if no error?" +[#28]: https://github.com/jprichardson/node-jsonfile/issues/28 "writeFile options argument broken " +[#27]: https://github.com/jprichardson/node-jsonfile/pull/27 "Use svg instead of png to get better image quality" +[#26]: https://github.com/jprichardson/node-jsonfile/issues/26 "Breaking change to fs-extra" +[#25]: https://github.com/jprichardson/node-jsonfile/issues/25 "support string encoding param for read methods" +[#24]: https://github.com/jprichardson/node-jsonfile/issues/24 "readFile: Passing in null options with a callback throws an error" +[#23]: https://github.com/jprichardson/node-jsonfile/pull/23 "Add appendFile and appendFileSync" +[#22]: https://github.com/jprichardson/node-jsonfile/issues/22 "Default value for spaces in readme.md is outdated" +[#21]: https://github.com/jprichardson/node-jsonfile/pull/21 "Update license attribute" +[#20]: https://github.com/jprichardson/node-jsonfile/issues/20 "Add simple caching functionallity" +[#19]: https://github.com/jprichardson/node-jsonfile/pull/19 "Add appendFileSync method" +[#18]: https://github.com/jprichardson/node-jsonfile/issues/18 "Add updateFile and updateFileSync methods" +[#17]: https://github.com/jprichardson/node-jsonfile/issues/17 "seem read & write sync has sequentially problem" +[#16]: https://github.com/jprichardson/node-jsonfile/pull/16 "export spaces defaulted to null" +[#15]: https://github.com/jprichardson/node-jsonfile/issues/15 "`jsonfile.spaces` should default to `null`" +[#14]: https://github.com/jprichardson/node-jsonfile/pull/14 "Add EOL at EOF" +[#13]: https://github.com/jprichardson/node-jsonfile/issues/13 "Add a final newline" +[#12]: https://github.com/jprichardson/node-jsonfile/issues/12 "readFile doesn't accept options" +[#11]: https://github.com/jprichardson/node-jsonfile/pull/11 "Added try,catch to readFileSync" +[#10]: https://github.com/jprichardson/node-jsonfile/issues/10 "No output or error from writeFile" +[#9]: https://github.com/jprichardson/node-jsonfile/pull/9 "Change 'js' to 'jf' in example." +[#8]: https://github.com/jprichardson/node-jsonfile/pull/8 "Updated forgotten module.exports to me." +[#7]: https://github.com/jprichardson/node-jsonfile/pull/7 "Add file name in error message" +[#6]: https://github.com/jprichardson/node-jsonfile/pull/6 "Use graceful-fs when possible" +[#5]: https://github.com/jprichardson/node-jsonfile/pull/5 "Jsonfile doesn't behave nicely when used inside a test suite." +[#4]: https://github.com/jprichardson/node-jsonfile/pull/4 "Added options parameter to writeFile and writeFileSync" +[#3]: https://github.com/jprichardson/node-jsonfile/issues/3 "test2" +[#2]: https://github.com/jprichardson/node-jsonfile/issues/2 "homepage field must be a string url. Deleted." +[#1]: https://github.com/jprichardson/node-jsonfile/pull/1 "adding an `.npmignore` file" diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/LICENSE new file mode 100644 index 0000000000..cb7e807b9b --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/LICENSE @@ -0,0 +1,15 @@ +(The MIT License) + +Copyright (c) 2012-2015, JP Richardson + +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. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/README.md b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/README.md new file mode 100644 index 0000000000..54bca05304 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/README.md @@ -0,0 +1,162 @@ +Node.js - jsonfile +================ + +Easily read/write JSON files. + +[![npm Package](https://img.shields.io/npm/v/jsonfile.svg?style=flat-square)](https://www.npmjs.org/package/jsonfile) +[![build status](https://secure.travis-ci.org/jprichardson/node-jsonfile.svg)](http://travis-ci.org/jprichardson/node-jsonfile) +[![windows Build status](https://img.shields.io/appveyor/ci/jprichardson/node-jsonfile/master.svg?label=windows%20build)](https://ci.appveyor.com/project/jprichardson/node-jsonfile/branch/master) + +Standard JavaScript + +Why? +---- + +Writing `JSON.stringify()` and then `fs.writeFile()` and `JSON.parse()` with `fs.readFile()` enclosed in `try/catch` blocks became annoying. + + + +Installation +------------ + + npm install --save jsonfile + + + +API +--- + +### readFile(filename, [options], callback) + +`options` (`object`, default `undefined`): Pass in any `fs.readFile` options or set `reviver` for a [JSON reviver](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). + - `throws` (`boolean`, default: `true`). If `JSON.parse` throws an error, pass this error to the callback. + If `false`, returns `null` for the object. + + +```js +var jsonfile = require('jsonfile') +var file = '/tmp/data.json' +jsonfile.readFile(file, function(err, obj) { + console.dir(obj) +}) +``` + + +### readFileSync(filename, [options]) + +`options` (`object`, default `undefined`): Pass in any `fs.readFileSync` options or set `reviver` for a [JSON reviver](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). +- `throws` (`boolean`, default: `true`). If `JSON.parse` throws an error, throw the error. +If `false`, returns `null` for the object. + +```js +var jsonfile = require('jsonfile') +var file = '/tmp/data.json' + +console.dir(jsonfile.readFileSync(file)) +``` + + +### writeFile(filename, obj, [options], callback) + +`options`: Pass in any `fs.writeFile` options or set `replacer` for a [JSON replacer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Can also pass in `spaces`. + + +```js +var jsonfile = require('jsonfile') + +var file = '/tmp/data.json' +var obj = {name: 'JP'} + +jsonfile.writeFile(file, obj, function (err) { + console.error(err) +}) +``` + +**formatting with spaces:** + +```js +var jsonfile = require('jsonfile') + +var file = '/tmp/data.json' +var obj = {name: 'JP'} + +jsonfile.writeFile(file, obj, {spaces: 2}, function(err) { + console.error(err) +}) +``` + + +### writeFileSync(filename, obj, [options]) + +`options`: Pass in any `fs.writeFileSync` options or set `replacer` for a [JSON replacer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Can also pass in `spaces`. + +```js +var jsonfile = require('jsonfile') + +var file = '/tmp/data.json' +var obj = {name: 'JP'} + +jsonfile.writeFileSync(file, obj) +``` + +**formatting with spaces:** + +```js +var jsonfile = require('jsonfile') + +var file = '/tmp/data.json' +var obj = {name: 'JP'} + +jsonfile.writeFileSync(file, obj, {spaces: 2}) +``` + + + +### spaces + +Global configuration to set spaces to indent JSON files. + +**default:** `null` + +```js +var jsonfile = require('jsonfile') + +jsonfile.spaces = 4 + +var file = '/tmp/data.json' +var obj = {name: 'JP'} + +// json file has four space indenting now +jsonfile.writeFile(file, obj, function (err) { + console.error(err) +}) +``` + +Note, it's bound to `this.spaces`. So, if you do this: + +```js +var myObj = {} +myObj.writeJsonSync = jsonfile.writeFileSync +// => this.spaces = null +``` + +Could do the following: + +```js +var jsonfile = require('jsonfile') +jsonfile.spaces = 4 +jsonfile.writeFileSync(file, obj) // will have 4 spaces indentation + +var myCrazyObj = {spaces: 32} +myCrazyObj.writeJsonSync = jsonfile.writeFileSync +myCrazyObj.writeJsonSync(file, obj) // will have 32 space indentation +myCrazyObj.writeJsonSync(file, obj, {spaces: 2}) // will have only 2 +``` + + +License +------- + +(MIT License) + +Copyright 2012-2016, JP Richardson diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/appveyor.yml b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/appveyor.yml new file mode 100644 index 0000000000..872af18deb --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/appveyor.yml @@ -0,0 +1,28 @@ +# Test against this version of Node.js +environment: + matrix: + # node.js + - nodejs_version: "0.10" + - nodejs_version: "0.12" + - nodejs_version: "4" + - nodejs_version: "5" + - nodejs_version: "6" + +# Install scripts. (runs after repo cloning) +install: + # Get the latest stable version of Node.js or io.js + - ps: Install-Product node $env:nodejs_version + # install modules + - npm config set loglevel warn + - npm install --silent + +# Post-install test scripts. +test_script: + # Output useful info for debugging. + - node --version + - npm --version + # run tests + - npm test + +# Don't actually build. +build: off diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/index.js b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/index.js new file mode 100644 index 0000000000..7111e15ae3 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/index.js @@ -0,0 +1,133 @@ +var _fs +try { + _fs = require('graceful-fs') +} catch (_) { + _fs = require('fs') +} + +function readFile (file, options, callback) { + if (callback == null) { + callback = options + options = {} + } + + if (typeof options === 'string') { + options = {encoding: options} + } + + options = options || {} + var fs = options.fs || _fs + + var shouldThrow = true + // DO NOT USE 'passParsingErrors' THE NAME WILL CHANGE!!!, use 'throws' instead + if ('passParsingErrors' in options) { + shouldThrow = options.passParsingErrors + } else if ('throws' in options) { + shouldThrow = options.throws + } + + fs.readFile(file, options, function (err, data) { + if (err) return callback(err) + + data = stripBom(data) + + var obj + try { + obj = JSON.parse(data, options ? options.reviver : null) + } catch (err2) { + if (shouldThrow) { + err2.message = file + ': ' + err2.message + return callback(err2) + } else { + return callback(null, null) + } + } + + callback(null, obj) + }) +} + +function readFileSync (file, options) { + options = options || {} + if (typeof options === 'string') { + options = {encoding: options} + } + + var fs = options.fs || _fs + + var shouldThrow = true + // DO NOT USE 'passParsingErrors' THE NAME WILL CHANGE!!!, use 'throws' instead + if ('passParsingErrors' in options) { + shouldThrow = options.passParsingErrors + } else if ('throws' in options) { + shouldThrow = options.throws + } + + var content = fs.readFileSync(file, options) + content = stripBom(content) + + try { + return JSON.parse(content, options.reviver) + } catch (err) { + if (shouldThrow) { + err.message = file + ': ' + err.message + throw err + } else { + return null + } + } +} + +function writeFile (file, obj, options, callback) { + if (callback == null) { + callback = options + options = {} + } + options = options || {} + var fs = options.fs || _fs + + var spaces = typeof options === 'object' && options !== null + ? 'spaces' in options + ? options.spaces : this.spaces + : this.spaces + + var str = '' + try { + str = JSON.stringify(obj, options ? options.replacer : null, spaces) + '\n' + } catch (err) { + if (callback) return callback(err, null) + } + + fs.writeFile(file, str, options, callback) +} + +function writeFileSync (file, obj, options) { + options = options || {} + var fs = options.fs || _fs + + var spaces = typeof options === 'object' && options !== null + ? 'spaces' in options + ? options.spaces : this.spaces + : this.spaces + + var str = JSON.stringify(obj, options.replacer, spaces) + '\n' + // not sure if fs.writeFileSync returns anything, but just in case + return fs.writeFileSync(file, str, options) +} + +function stripBom (content) { + // we do this because JSON.parse would convert it to a utf8 string if encoding wasn't specified + if (Buffer.isBuffer(content)) content = content.toString('utf8') + content = content.replace(/^\uFEFF/, '') + return content +} + +var jsonfile = { + spaces: null, + readFile: readFile, + readFileSync: readFileSync, + writeFile: writeFile, + writeFileSync: writeFileSync +} + +module.exports = jsonfile diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/package.json new file mode 100644 index 0000000000..63403c75aa --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonfile/package.json @@ -0,0 +1,72 @@ +{ + "_args": [ + [ + "jsonfile@2.4.0", + "/private/var/lib/jenkins/workspace/iconik_panel/src" + ] + ], + "_from": "jsonfile@2.4.0", + "_id": "jsonfile@2.4.0", + "_inBundle": false, + "_integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "_location": "/jsonfile", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "jsonfile@2.4.0", + "name": "jsonfile", + "escapedName": "jsonfile", + "rawSpec": "2.4.0", + "saveSpec": null, + "fetchSpec": "2.4.0" + }, + "_requiredBy": [ + "/fs-extra" + ], + "_resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "_spec": "2.4.0", + "_where": "/private/var/lib/jenkins/workspace/iconik_panel/src", + "author": { + "name": "JP Richardson", + "email": "jprichardson@gmail.com" + }, + "bugs": { + "url": "https://github.com/jprichardson/node-jsonfile/issues" + }, + "dependencies": { + "graceful-fs": "^4.1.6" + }, + "description": "Easily read/write JSON files.", + "devDependencies": { + "mocha": "2.x", + "mock-fs": "^3.8.0", + "rimraf": "^2.4.0", + "standard": "^6.0.8" + }, + "homepage": "https://github.com/jprichardson/node-jsonfile#readme", + "keywords": [ + "read", + "write", + "file", + "json", + "fs", + "fs-extra" + ], + "license": "MIT", + "main": "index.js", + "name": "jsonfile", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/jprichardson/node-jsonfile.git" + }, + "scripts": { + "lint": "standard", + "test": "npm run lint && npm run unit", + "unit": "mocha" + }, + "version": "2.4.0" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/README.markdown b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/README.markdown new file mode 100644 index 0000000000..71d9a93b59 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/README.markdown @@ -0,0 +1,34 @@ +jsonify +======= + +This module provides Douglas Crockford's JSON implementation without modifying +any globals. + +`stringify` and `parse` are merely exported without respect to whether or not a +global `JSON` object exists. + +methods +======= + +var json = require('jsonify'); + +json.parse(source, reviver) +--------------------------- + +Return a new javascript object from a parse of the `source` string. + +If a `reviver` function is specified, walk the structure passing each name/value +pair to `reviver.call(parent, key, value)` to transform the `value` before +parsing it. + +json.stringify(value, replacer, space) +-------------------------------------- + +Return a string representation for `value`. + +If `replacer` is specified, walk the structure passing each name/value pair to +`replacer.call(parent, key, value)` to transform the `value` before stringifying +it. + +If `space` is a number, indent the result by that many spaces. +If `space` is a string, use `space` as the indentation. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/index.js b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/index.js new file mode 100644 index 0000000000..f728a1605a --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/index.js @@ -0,0 +1,2 @@ +exports.parse = require('./lib/parse'); +exports.stringify = require('./lib/stringify'); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/parse.js b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/parse.js new file mode 100644 index 0000000000..30e2f01436 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/parse.js @@ -0,0 +1,273 @@ +var at, // The index of the current character + ch, // The current character + escapee = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' + }, + text, + + error = function (m) { + // Call error when something is wrong. + throw { + name: 'SyntaxError', + message: m, + at: at, + text: text + }; + }, + + next = function (c) { + // If a c parameter is provided, verify that it matches the current character. + if (c && c !== ch) { + error("Expected '" + c + "' instead of '" + ch + "'"); + } + + // Get the next character. When there are no more characters, + // return the empty string. + + ch = text.charAt(at); + at += 1; + return ch; + }, + + number = function () { + // Parse a number value. + var number, + string = ''; + + if (ch === '-') { + string = '-'; + next('-'); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (!isFinite(number)) { + error("Bad number"); + } else { + return number; + } + }, + + string = function () { + // Parse a string value. + var hex, + i, + string = '', + uffff; + + // When parsing for string values, we must look for " and \ characters. + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + error("Bad string"); + }, + + white = function () { + +// Skip whitespace. + + while (ch && ch <= ' ') { + next(); + } + }, + + word = function () { + +// true, false, or null. + + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error("Unexpected '" + ch + "'"); + }, + + value, // Place holder for the value function. + + array = function () { + +// Parse an array value. + + var array = []; + + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error("Bad array"); + }, + + object = function () { + +// Parse an object value. + + var key, + object = {}; + + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + if (Object.hasOwnProperty.call(object, key)) { + error('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error("Bad object"); + }; + +value = function () { + +// Parse a JSON value. It could be an object, an array, a string, a number, +// or a word. + + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } +}; + +// Return the json_parse function. It will have access to all of the above +// functions and variables. + +module.exports = function (source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error("Syntax error"); + } + + // If there is a reviver function, we recursively walk the new structure, + // passing each name/value pair to the reviver function for possible + // transformation, starting with a temporary root object that holds the result + // in an empty key. If there is not a reviver function, we simply return the + // result. + + return typeof reviver === 'function' ? (function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({'': result}, '')) : result; +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/stringify.js b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/stringify.js new file mode 100644 index 0000000000..1345870814 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/lib/stringify.js @@ -0,0 +1,154 @@ +var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + +function quote(string) { + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; +} + +function str(key, holder) { + // Produce a string from holder[key]. + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + + // If the value has a toJSON method, call it to obtain a replacement value. + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + + // What happens next depends on the value's type. + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + // JSON numbers must be finite. Encode non-finite numbers as null. + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. + return String(value); + + case 'object': + if (!value) return 'null'; + gap += indent; + partial = []; + + // Array.isArray + if (Object.prototype.toString.apply(value) === '[object Array]') { + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + + // Join all of the elements together, separated with commas, and + // wrap them in brackets. + v = partial.length === 0 ? '[]' : gap ? + '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + // If the replacer is an array, use it to select the members to be + // stringified. + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + else { + // Otherwise, iterate through all of the keys in the object. + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + + // Join all of the member texts together, separated with commas, + // and wrap them in braces. + + v = partial.length === 0 ? '{}' : gap ? + '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : + '{' + partial.join(',') + '}'; + gap = mind; + return v; + } +} + +module.exports = function (value, replacer, space) { + var i; + gap = ''; + indent = ''; + + // If the space parameter is a number, make an indent string containing that + // many spaces. + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + } + // If the space parameter is a string, it will be used as the indent string. + else if (typeof space === 'string') { + indent = space; + } + + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. + rep = replacer; + if (replacer && typeof replacer !== 'function' + && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + + // Make a fake root object containing our value under the key of ''. + // Return the result of stringifying the value. + return str('', {'': value}); +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/package.json new file mode 100644 index 0000000000..c377a532c0 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "jsonify@~0.0.0", + "scope": null, + "escapedName": "jsonify", + "name": "jsonify", + "rawSpec": "~0.0.0", + "spec": ">=0.0.0 <0.1.0", + "type": "range" + }, + "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/json-stable-stringify" + ] + ], + "_defaultsLoaded": true, + "_engineSupported": true, + "_from": "jsonify@>=0.0.0 <0.1.0", + "_id": "jsonify@0.0.0", + "_inCache": true, + "_location": "/jsonify", + "_nodeVersion": "v0.5.0-pre", + "_npmVersion": "1.0.10", + "_phantomChildren": {}, + "_requested": { + "raw": "jsonify@~0.0.0", + "scope": null, + "escapedName": "jsonify", + "name": "jsonify", + "rawSpec": "~0.0.0", + "spec": ">=0.0.0 <0.1.0", + "type": "range" + }, + "_requiredBy": [ + "/json-stable-stringify" + ], + "_resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "_shasum": "2c74b6ee41d93ca51b7b5aaee8f503631d252a73", + "_shrinkwrap": null, + "_spec": "jsonify@~0.0.0", + "_where": "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/json-stable-stringify", + "author": { + "name": "Douglas Crockford", + "url": "http://crockford.com/" + }, + "bugs": { + "url": "https://github.com/substack/jsonify/issues" + }, + "dependencies": {}, + "description": "JSON without touching any globals", + "devDependencies": { + "garbage": "0.0.x", + "tap": "0.0.x" + }, + "directories": { + "lib": ".", + "test": "test" + }, + "dist": { + "shasum": "2c74b6ee41d93ca51b7b5aaee8f503631d252a73", + "tarball": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/substack/jsonify#readme", + "keywords": [ + "json", + "browser" + ], + "license": "Public Domain", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "jsonify", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/jsonify.git" + }, + "scripts": { + "test": "tap test" + }, + "version": "0.0.0" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/parse.js b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/parse.js new file mode 100644 index 0000000000..e2313f55a0 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/parse.js @@ -0,0 +1,16 @@ +var test = require('tap').test; +var json = require('../'); +var garbage = require('garbage'); + +test('parse', function (t) { + for (var i = 0; i < 50; i++) { + var s = JSON.stringify(garbage(50)); + + t.deepEqual( + json.parse(s), + JSON.parse(s) + ); + } + + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/stringify.js b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/stringify.js new file mode 100644 index 0000000000..89b0b6703f --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/jsonify/test/stringify.js @@ -0,0 +1,15 @@ +var test = require('tap').test; +var json = require('../'); +var garbage = require('garbage'); + +test('stringify', function (t) { + for (var i = 0; i < 50; i++) { + var obj = garbage(50); + t.equal( + json.stringify(obj), + JSON.stringify(obj) + ); + } + + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.npmignore b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.npmignore new file mode 100644 index 0000000000..9303c347ee --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.travis.yml b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.travis.yml new file mode 100644 index 0000000000..c693a939df --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - "0.10" diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/LICENSE new file mode 100644 index 0000000000..432d1aeb01 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/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: + +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. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/cmd.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/cmd.js new file mode 100644 index 0000000000..d95de15ae9 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/cmd.js @@ -0,0 +1,33 @@ +#!/usr/bin/env node + +var mkdirp = require('../'); +var minimist = require('minimist'); +var fs = require('fs'); + +var argv = minimist(process.argv.slice(2), { + alias: { m: 'mode', h: 'help' }, + string: [ 'mode' ] +}); +if (argv.help) { + fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout); + return; +} + +var paths = argv._.slice(); +var mode = argv.mode ? parseInt(argv.mode, 8) : undefined; + +(function next () { + if (paths.length === 0) return; + var p = paths.shift(); + + if (mode === undefined) mkdirp(p, cb) + else mkdirp(p, mode, cb) + + function cb (err) { + if (err) { + console.error(err.message); + process.exit(1); + } + else next(); + } +})(); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/usage.txt b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/usage.txt new file mode 100644 index 0000000000..f952aa2c7a --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/bin/usage.txt @@ -0,0 +1,12 @@ +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories that + don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m, --mode If a directory needs to be created, set the mode as an octal + permission string. + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/examples/pow.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/examples/pow.js new file mode 100644 index 0000000000..e6924212e6 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/examples/pow.js @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/index.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/index.js new file mode 100644 index 0000000000..a1742b2069 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/index.js @@ -0,0 +1,97 @@ +var path = require('path'); +var fs = require('fs'); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; + } + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); +} + +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = 0777 & (~process.umask()); + } + if (!made) made = null; + + p = path.resolve(p); + + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } + + return made; +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/.travis.yml b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/.travis.yml new file mode 100644 index 0000000000..cc4dba29d9 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/LICENSE new file mode 100644 index 0000000000..ee27ba4b44 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/LICENSE @@ -0,0 +1,18 @@ +This software is released under the MIT 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: + +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. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/example/parse.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/example/parse.js new file mode 100644 index 0000000000..abff3e8ee8 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/example/parse.js @@ -0,0 +1,2 @@ +var argv = require('../')(process.argv.slice(2)); +console.dir(argv); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/index.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/index.js new file mode 100644 index 0000000000..584f551a6d --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/index.js @@ -0,0 +1,187 @@ +module.exports = function (args, opts) { + if (!opts) opts = {}; + + var flags = { bools : {}, strings : {} }; + + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + flags.bools[key] = true; + }); + + [].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true; + }); + + var aliases = {}; + Object.keys(opts.alias || {}).forEach(function (key) { + aliases[key] = [].concat(opts.alias[key]); + aliases[key].forEach(function (x) { + aliases[x] = [key].concat(aliases[key].filter(function (y) { + return x !== y; + })); + }); + }); + + var defaults = opts['default'] || {}; + + var argv = { _ : [] }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] === undefined ? false : defaults[key]); + }); + + var notFlags = []; + + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--')+1); + args = args.slice(0, args.indexOf('--')); + } + + function setArg (key, val) { + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val + ; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (/^--.+=/.test(arg)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + setArg(m[1], m[2]); + } + else if (/^--no-.+/.test(arg)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false); + } + else if (/^--.+/.test(arg)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !/^-/.test(next) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, next); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true'); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true); + } + } + else if (/^-[^-]+/.test(arg)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j+2); + + if (next === '-') { + setArg(letters[j], next) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next); + broken = true; + break; + } + + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2)); + broken = true; + break; + } + else { + setArg(letters[j], flags.strings[letters[j]] ? '' : true); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, args[i+1]); + i++; + } + else if (args[i+1] && /true|false/.test(args[i+1])) { + setArg(key, args[i+1] === 'true'); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true); + } + } + } + else { + argv._.push( + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) + ); + } + } + + Object.keys(defaults).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) { + setKey(argv, key.split('.'), defaults[key]); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[key]); + }); + } + }); + + notFlags.forEach(function(key) { + argv._.push(key); + }); + + return argv; +}; + +function hasKey (obj, keys) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + o = (o[key] || {}); + }); + + var key = keys[keys.length - 1]; + return key in o; +} + +function setKey (obj, keys, value) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + if (o[key] === undefined) o[key] = {}; + o = o[key]; + }); + + var key = keys[keys.length - 1]; + if (o[key] === undefined || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } +} + +function isNumber (x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} + +function longest (xs) { + return Math.max.apply(null, xs.map(function (x) { return x.length })); +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/package.json new file mode 100644 index 0000000000..4a4cebefbe --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + { + "raw": "minimist@0.0.8", + "scope": null, + "escapedName": "minimist", + "name": "minimist", + "rawSpec": "0.0.8", + "spec": "0.0.8", + "type": "version" + }, + "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/mkdirp" + ] + ], + "_from": "minimist@0.0.8", + "_id": "minimist@0.0.8", + "_inCache": true, + "_location": "/mkdirp/minimist", + "_npmUser": { + "name": "substack", + "email": "mail@substack.net" + }, + "_npmVersion": "1.4.3", + "_phantomChildren": {}, + "_requested": { + "raw": "minimist@0.0.8", + "scope": null, + "escapedName": "minimist", + "name": "minimist", + "rawSpec": "0.0.8", + "spec": "0.0.8", + "type": "version" + }, + "_requiredBy": [ + "/mkdirp" + ], + "_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "_shasum": "857fcabfc3397d2625b8228262e86aa7a011b05d", + "_shrinkwrap": null, + "_spec": "minimist@0.0.8", + "_where": "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/mkdirp", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "bugs": { + "url": "https://github.com/substack/minimist/issues" + }, + "dependencies": {}, + "description": "parse argument options", + "devDependencies": { + "tap": "~0.4.0", + "tape": "~1.0.4" + }, + "directories": {}, + "dist": { + "shasum": "857fcabfc3397d2625b8228262e86aa7a011b05d", + "tarball": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + }, + "homepage": "https://github.com/substack/minimist", + "keywords": [ + "argv", + "getopt", + "parser", + "optimist" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "minimist", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/minimist.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/6..latest", + "ff/5", + "firefox/latest", + "chrome/10", + "chrome/latest", + "safari/5.1", + "safari/latest", + "opera/12" + ] + }, + "version": "0.0.8" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/readme.markdown b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/readme.markdown new file mode 100644 index 0000000000..c25635323e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/readme.markdown @@ -0,0 +1,73 @@ +# minimist + +parse argument options + +This module is the guts of optimist's argument parser without all the +fanciful decoration. + +[![browser support](https://ci.testling.com/substack/minimist.png)](http://ci.testling.com/substack/minimist) + +[![build status](https://secure.travis-ci.org/substack/minimist.png)](http://travis-ci.org/substack/minimist) + +# example + +``` js +var argv = require('minimist')(process.argv.slice(2)); +console.dir(argv); +``` + +``` +$ node example/parse.js -a beep -b boop +{ _: [], a: 'beep', b: 'boop' } +``` + +``` +$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz +{ _: [ 'foo', 'bar', 'baz' ], + x: 3, + y: 4, + n: 5, + a: true, + b: true, + c: true, + beep: 'boop' } +``` + +# methods + +``` js +var parseArgs = require('minimist') +``` + +## var argv = parseArgs(args, opts={}) + +Return an argument object `argv` populated with the array arguments from `args`. + +`argv._` contains all the arguments that didn't have an option associated with +them. + +Numeric-looking arguments will be returned as numbers unless `opts.string` or +`opts.boolean` is set for that argument name. + +Any arguments after `'--'` will not be parsed and will end up in `argv._`. + +options can be: + +* `opts.string` - a string or array of strings argument names to always treat as +strings +* `opts.boolean` - a string or array of strings to always treat as booleans +* `opts.alias` - an object mapping string names to strings or arrays of string +argument names to use as aliases +* `opts.default` - an object mapping string argument names to default values + +# install + +With [npm](https://npmjs.org) do: + +``` +npm install minimist +``` + +# license + +MIT diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dash.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dash.js new file mode 100644 index 0000000000..8b034b99a9 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dash.js @@ -0,0 +1,24 @@ +var parse = require('../'); +var test = require('tape'); + +test('-', function (t) { + t.plan(5); + t.deepEqual(parse([ '-n', '-' ]), { n: '-', _: [] }); + t.deepEqual(parse([ '-' ]), { _: [ '-' ] }); + t.deepEqual(parse([ '-f-' ]), { f: '-', _: [] }); + t.deepEqual( + parse([ '-b', '-' ], { boolean: 'b' }), + { b: true, _: [ '-' ] } + ); + t.deepEqual( + parse([ '-s', '-' ], { string: 's' }), + { s: '-', _: [] } + ); +}); + +test('-a -- b', function (t) { + t.plan(3); + t.deepEqual(parse([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] }); + t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] }); + t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/default_bool.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/default_bool.js new file mode 100644 index 0000000000..f0041ee40c --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/default_bool.js @@ -0,0 +1,20 @@ +var test = require('tape'); +var parse = require('../'); + +test('boolean default true', function (t) { + var argv = parse([], { + boolean: 'sometrue', + default: { sometrue: true } + }); + t.equal(argv.sometrue, true); + t.end(); +}); + +test('boolean default false', function (t) { + var argv = parse([], { + boolean: 'somefalse', + default: { somefalse: false } + }); + t.equal(argv.somefalse, false); + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dotted.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dotted.js new file mode 100644 index 0000000000..ef0ae349bf --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/dotted.js @@ -0,0 +1,16 @@ +var parse = require('../'); +var test = require('tape'); + +test('dotted alias', function (t) { + var argv = parse(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}}); + t.equal(argv.a.b, 22); + t.equal(argv.aa.bb, 22); + t.end(); +}); + +test('dotted default', function (t) { + var argv = parse('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}}); + t.equal(argv.a.b, 11); + t.equal(argv.aa.bb, 11); + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/long.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/long.js new file mode 100644 index 0000000000..5d3a1e09d3 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/long.js @@ -0,0 +1,31 @@ +var test = require('tape'); +var parse = require('../'); + +test('long opts', function (t) { + t.deepEqual( + parse([ '--bool' ]), + { bool : true, _ : [] }, + 'long boolean' + ); + t.deepEqual( + parse([ '--pow', 'xixxle' ]), + { pow : 'xixxle', _ : [] }, + 'long capture sp' + ); + t.deepEqual( + parse([ '--pow=xixxle' ]), + { pow : 'xixxle', _ : [] }, + 'long capture eq' + ); + t.deepEqual( + parse([ '--host', 'localhost', '--port', '555' ]), + { host : 'localhost', port : 555, _ : [] }, + 'long captures sp' + ); + t.deepEqual( + parse([ '--host=localhost', '--port=555' ]), + { host : 'localhost', port : 555, _ : [] }, + 'long captures eq' + ); + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse.js new file mode 100644 index 0000000000..8a90646696 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse.js @@ -0,0 +1,318 @@ +var parse = require('../'); +var test = require('tape'); + +test('parse args', function (t) { + t.deepEqual( + parse([ '--no-moo' ]), + { moo : false, _ : [] }, + 'no' + ); + t.deepEqual( + parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]), + { v : ['a','b','c'], _ : [] }, + 'multi' + ); + t.end(); +}); + +test('comprehensive', function (t) { + t.deepEqual( + parse([ + '--name=meowmers', 'bare', '-cats', 'woo', + '-h', 'awesome', '--multi=quux', + '--key', 'value', + '-b', '--bool', '--no-meep', '--multi=baz', + '--', '--not-a-flag', 'eek' + ]), + { + c : true, + a : true, + t : true, + s : 'woo', + h : 'awesome', + b : true, + bool : true, + key : 'value', + multi : [ 'quux', 'baz' ], + meep : false, + name : 'meowmers', + _ : [ 'bare', '--not-a-flag', 'eek' ] + } + ); + t.end(); +}); + +test('nums', function (t) { + var argv = parse([ + '-x', '1234', + '-y', '5.67', + '-z', '1e7', + '-w', '10f', + '--hex', '0xdeadbeef', + '789' + ]); + t.deepEqual(argv, { + x : 1234, + y : 5.67, + z : 1e7, + w : '10f', + hex : 0xdeadbeef, + _ : [ 789 ] + }); + t.deepEqual(typeof argv.x, 'number'); + t.deepEqual(typeof argv.y, 'number'); + t.deepEqual(typeof argv.z, 'number'); + t.deepEqual(typeof argv.w, 'string'); + t.deepEqual(typeof argv.hex, 'number'); + t.deepEqual(typeof argv._[0], 'number'); + t.end(); +}); + +test('flag boolean', function (t) { + var argv = parse([ '-t', 'moo' ], { boolean: 't' }); + t.deepEqual(argv, { t : true, _ : [ 'moo' ] }); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); +}); + +test('flag boolean value', function (t) { + var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], { + boolean: [ 't', 'verbose' ], + default: { verbose: true } + }); + + t.deepEqual(argv, { + verbose: false, + t: true, + _: ['moo'] + }); + + t.deepEqual(typeof argv.verbose, 'boolean'); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); +}); + +test('flag boolean default false', function (t) { + var argv = parse(['moo'], { + boolean: ['t', 'verbose'], + default: { verbose: false, t: false } + }); + + t.deepEqual(argv, { + verbose: false, + t: false, + _: ['moo'] + }); + + t.deepEqual(typeof argv.verbose, 'boolean'); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); + +}); + +test('boolean groups', function (t) { + var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], { + boolean: ['x','y','z'] + }); + + t.deepEqual(argv, { + x : true, + y : false, + z : true, + _ : [ 'one', 'two', 'three' ] + }); + + t.deepEqual(typeof argv.x, 'boolean'); + t.deepEqual(typeof argv.y, 'boolean'); + t.deepEqual(typeof argv.z, 'boolean'); + t.end(); +}); + +test('newlines in params' , function (t) { + var args = parse([ '-s', "X\nX" ]) + t.deepEqual(args, { _ : [], s : "X\nX" }); + + // reproduce in bash: + // VALUE="new + // line" + // node program.js --s="$VALUE" + args = parse([ "--s=X\nX" ]) + t.deepEqual(args, { _ : [], s : "X\nX" }); + t.end(); +}); + +test('strings' , function (t) { + var s = parse([ '-s', '0001234' ], { string: 's' }).s; + t.equal(s, '0001234'); + t.equal(typeof s, 'string'); + + var x = parse([ '-x', '56' ], { string: 'x' }).x; + t.equal(x, '56'); + t.equal(typeof x, 'string'); + t.end(); +}); + +test('stringArgs', function (t) { + var s = parse([ ' ', ' ' ], { string: '_' })._; + t.same(s.length, 2); + t.same(typeof s[0], 'string'); + t.same(s[0], ' '); + t.same(typeof s[1], 'string'); + t.same(s[1], ' '); + t.end(); +}); + +test('empty strings', function(t) { + var s = parse([ '-s' ], { string: 's' }).s; + t.equal(s, ''); + t.equal(typeof s, 'string'); + + var str = parse([ '--str' ], { string: 'str' }).str; + t.equal(str, ''); + t.equal(typeof str, 'string'); + + var letters = parse([ '-art' ], { + string: [ 'a', 't' ] + }); + + t.equal(letters.a, ''); + t.equal(letters.r, true); + t.equal(letters.t, ''); + + t.end(); +}); + + +test('slashBreak', function (t) { + t.same( + parse([ '-I/foo/bar/baz' ]), + { I : '/foo/bar/baz', _ : [] } + ); + t.same( + parse([ '-xyz/foo/bar/baz' ]), + { x : true, y : true, z : '/foo/bar/baz', _ : [] } + ); + t.end(); +}); + +test('alias', function (t) { + var argv = parse([ '-f', '11', '--zoom', '55' ], { + alias: { z: 'zoom' } + }); + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.f, 11); + t.end(); +}); + +test('multiAlias', function (t) { + var argv = parse([ '-f', '11', '--zoom', '55' ], { + alias: { z: [ 'zm', 'zoom' ] } + }); + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.z, argv.zm); + t.equal(argv.f, 11); + t.end(); +}); + +test('nested dotted objects', function (t) { + var argv = parse([ + '--foo.bar', '3', '--foo.baz', '4', + '--foo.quux.quibble', '5', '--foo.quux.o_O', + '--beep.boop' + ]); + + t.same(argv.foo, { + bar : 3, + baz : 4, + quux : { + quibble : 5, + o_O : true + } + }); + t.same(argv.beep, { boop : true }); + t.end(); +}); + +test('boolean and alias with chainable api', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = parse(aliased, { + boolean: 'herp', + alias: { h: 'herp' } + }); + var propertyArgv = parse(regular, { + boolean: 'herp', + alias: { h: 'herp' } + }); + var expected = { + herp: true, + h: true, + '_': [ 'derp' ] + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +test('boolean and alias with options hash', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + alias: { 'h': 'herp' }, + boolean: 'herp' + }; + var aliasedArgv = parse(aliased, opts); + var propertyArgv = parse(regular, opts); + var expected = { + herp: true, + h: true, + '_': [ 'derp' ] + }; + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +test('boolean and alias using explicit true', function (t) { + var aliased = [ '-h', 'true' ]; + var regular = [ '--herp', 'true' ]; + var opts = { + alias: { h: 'herp' }, + boolean: 'h' + }; + var aliasedArgv = parse(aliased, opts); + var propertyArgv = parse(regular, opts); + var expected = { + herp: true, + h: true, + '_': [ ] + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +// regression, see https://github.com/substack/node-optimist/issues/71 +test('boolean and --x=true', function(t) { + var parsed = parse(['--boool', '--other=true'], { + boolean: 'boool' + }); + + t.same(parsed.boool, true); + t.same(parsed.other, 'true'); + + parsed = parse(['--boool', '--other=false'], { + boolean: 'boool' + }); + + t.same(parsed.boool, true); + t.same(parsed.other, 'false'); + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js new file mode 100644 index 0000000000..21851b036e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js @@ -0,0 +1,9 @@ +var parse = require('../'); +var test = require('tape'); + +test('parse with modifier functions' , function (t) { + t.plan(1); + + var argv = parse([ '-b', '123' ], { boolean: 'b' }); + t.deepEqual(argv, { b: true, _: ['123'] }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/short.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/short.js new file mode 100644 index 0000000000..d513a1c252 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/short.js @@ -0,0 +1,67 @@ +var parse = require('../'); +var test = require('tape'); + +test('numeric short args', function (t) { + t.plan(2); + t.deepEqual(parse([ '-n123' ]), { n: 123, _: [] }); + t.deepEqual( + parse([ '-123', '456' ]), + { 1: true, 2: true, 3: 456, _: [] } + ); +}); + +test('short', function (t) { + t.deepEqual( + parse([ '-b' ]), + { b : true, _ : [] }, + 'short boolean' + ); + t.deepEqual( + parse([ 'foo', 'bar', 'baz' ]), + { _ : [ 'foo', 'bar', 'baz' ] }, + 'bare' + ); + t.deepEqual( + parse([ '-cats' ]), + { c : true, a : true, t : true, s : true, _ : [] }, + 'group' + ); + t.deepEqual( + parse([ '-cats', 'meow' ]), + { c : true, a : true, t : true, s : 'meow', _ : [] }, + 'short group next' + ); + t.deepEqual( + parse([ '-h', 'localhost' ]), + { h : 'localhost', _ : [] }, + 'short capture' + ); + t.deepEqual( + parse([ '-h', 'localhost', '-p', '555' ]), + { h : 'localhost', p : 555, _ : [] }, + 'short captures' + ); + t.end(); +}); + +test('mixed short bool and capture', function (t) { + t.same( + parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ] + } + ); + t.end(); +}); + +test('short and long', function (t) { + t.deepEqual( + parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ] + } + ); + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/whitespace.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/whitespace.js new file mode 100644 index 0000000000..8a52a58cec --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/node_modules/minimist/test/whitespace.js @@ -0,0 +1,8 @@ +var parse = require('../'); +var test = require('tape'); + +test('whitespace should be whitespace' , function (t) { + t.plan(1); + var x = parse([ '-x', '\t' ]).x; + t.equal(x, '\t'); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/package.json new file mode 100644 index 0000000000..7f7f43c05b --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/package.json @@ -0,0 +1,91 @@ +{ + "_args": [ + [ + { + "raw": "mkdirp@0.5.0", + "scope": null, + "escapedName": "mkdirp", + "name": "mkdirp", + "rawSpec": "0.5.0", + "spec": "0.5.0", + "type": "version" + }, + "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/extract-zip" + ] + ], + "_from": "mkdirp@0.5.0", + "_id": "mkdirp@0.5.0", + "_inCache": true, + "_location": "/mkdirp", + "_npmUser": { + "name": "substack", + "email": "mail@substack.net" + }, + "_npmVersion": "1.4.3", + "_phantomChildren": {}, + "_requested": { + "raw": "mkdirp@0.5.0", + "scope": null, + "escapedName": "mkdirp", + "name": "mkdirp", + "rawSpec": "0.5.0", + "spec": "0.5.0", + "type": "version" + }, + "_requiredBy": [ + "/extract-zip" + ], + "_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "_shasum": "1d73076a6df986cd9344e15e71fcc05a4c9abf12", + "_shrinkwrap": null, + "_spec": "mkdirp@0.5.0", + "_where": "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/extract-zip", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "bugs": { + "url": "https://github.com/substack/node-mkdirp/issues" + }, + "dependencies": { + "minimist": "0.0.8" + }, + "description": "Recursively mkdir, like `mkdir -p`", + "devDependencies": { + "mock-fs": "~2.2.0", + "tap": "~0.4.0" + }, + "directories": {}, + "dist": { + "shasum": "1d73076a6df986cd9344e15e71fcc05a4c9abf12", + "tarball": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz" + }, + "homepage": "https://github.com/substack/node-mkdirp", + "keywords": [ + "mkdir", + "directory" + ], + "license": "MIT", + "main": "./index", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "mkdirp", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/substack/node-mkdirp.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "0.5.0" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/readme.markdown b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/readme.markdown new file mode 100644 index 0000000000..3cc1315385 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/readme.markdown @@ -0,0 +1,100 @@ +# mkdirp + +Like `mkdir -p`, but in node.js! + +[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp) + +# example + +## pow.js + +```js +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); +``` + +Output + +``` +pow! +``` + +And now /tmp/foo/bar/baz exists, huzzah! + +# methods + +```js +var mkdirp = require('mkdirp'); +``` + +## mkdirp(dir, opts, cb) + +Create a new directory and any necessary subdirectories at `dir` with octal +permission string `opts.mode`. If `opts` is a non-object, it will be treated as +the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +`cb(err, made)` fires with the error or the first directory `made` +that had to be created, if any. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdir(path, mode, cb)` and +`opts.fs.stat(path, cb)`. + +## mkdirp.sync(dir, opts) + +Synchronously create a new directory and any necessary subdirectories at `dir` +with octal permission string `opts.mode`. If `opts` is a non-object, it will be +treated as the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +Returns the first directory that had to be created, if any. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` and +`opts.fs.statSync(path)`. + +# usage + +This package also ships with a `mkdirp` command. + +``` +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories that + don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m, --mode If a directory needs to be created, set the mode as an octal + permission string. + +``` + +# install + +With [npm](http://npmjs.org) do: + +``` +npm install mkdirp +``` + +to get the library, or + +``` +npm install -g mkdirp +``` + +to get the command. + +# license + +MIT diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/chmod.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/chmod.js new file mode 100644 index 0000000000..520dcb8e9b --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/chmod.js @@ -0,0 +1,38 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +test('chmod-pre', function (t) { + var mode = 0744 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.equal(stat && stat.mode & 0777, mode, 'should be 0744'); + t.end(); + }); + }); +}); + +test('chmod', function (t) { + var mode = 0755 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.end(); + }); + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/clobber.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/clobber.js new file mode 100644 index 0000000000..0eb7099870 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/clobber.js @@ -0,0 +1,37 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +// a file in the way +var itw = ps.slice(0, 3).join('/'); + + +test('clobber-pre', function (t) { + console.error("about to write to "+itw) + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); + + fs.stat(itw, function (er, stat) { + t.ifError(er) + t.ok(stat && stat.isFile(), 'should be file') + t.end() + }) +}) + +test('clobber', function (t) { + t.plan(2); + mkdirp(file, 0755, function (err) { + t.ok(err); + t.equal(err.code, 'ENOTDIR'); + t.end(); + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/mkdirp.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/mkdirp.js new file mode 100644 index 0000000000..3b624ddbeb --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/mkdirp.js @@ -0,0 +1,26 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('woo', function (t) { + t.plan(5); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }) + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs.js new file mode 100644 index 0000000000..f1fbeca146 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs.js @@ -0,0 +1,27 @@ +var mkdirp = require('../'); +var path = require('path'); +var test = require('tap').test; +var mockfs = require('mock-fs'); + +test('opts.fs', function (t) { + t.plan(5); + + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/beep/boop/' + [x,y,z].join('/'); + var xfs = mockfs.fs(); + + mkdirp(file, { fs: xfs, mode: 0755 }, function (err) { + t.ifError(err); + xfs.exists(file, function (ex) { + t.ok(ex, 'created file'); + xfs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs_sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs_sync.js new file mode 100644 index 0000000000..224b50642f --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/opts_fs_sync.js @@ -0,0 +1,25 @@ +var mkdirp = require('../'); +var path = require('path'); +var test = require('tap').test; +var mockfs = require('mock-fs'); + +test('opts.fs sync', function (t) { + t.plan(4); + + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/beep/boop/' + [x,y,z].join('/'); + var xfs = mockfs.fs(); + + mkdirp.sync(file, { fs: xfs, mode: 0755 }); + xfs.exists(file, function (ex) { + t.ok(ex, 'created file'); + xfs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm.js new file mode 100644 index 0000000000..2c97590520 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm.js @@ -0,0 +1,30 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('async perm', function (t) { + t.plan(5); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); + + mkdirp(file, 0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }) + }); +}); + +test('async root perm', function (t) { + mkdirp('/tmp', 0755, function (err) { + if (err) t.fail(err); + t.end(); + }); + t.end(); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm_sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm_sync.js new file mode 100644 index 0000000000..327e54b2e9 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/perm_sync.js @@ -0,0 +1,34 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('sync perm', function (t) { + t.plan(4); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; + + mkdirp.sync(file, 0755); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); + +test('sync root perm', function (t) { + t.plan(3); + + var file = '/tmp'; + mkdirp.sync(file, 0755); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/race.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/race.js new file mode 100644 index 0000000000..7c295f410d --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/race.js @@ -0,0 +1,40 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('race', function (t) { + t.plan(6); + var ps = [ '', 'tmp' ]; + + for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); + } + var file = ps.join('/'); + + var res = 2; + mk(file, function () { + if (--res === 0) t.end(); + }); + + mk(file, function () { + if (--res === 0) t.end(); + }); + + function mk (file, cb) { + mkdirp(file, 0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + if (cb) cb(); + }); + }) + }); + } +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/rel.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/rel.js new file mode 100644 index 0000000000..d1f175c240 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/rel.js @@ -0,0 +1,30 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('rel', function (t) { + t.plan(5); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + process.chdir(cwd); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }) + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return.js new file mode 100644 index 0000000000..bce68e5613 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return.js @@ -0,0 +1,25 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, '/tmp/' + x); + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, null); + }); + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return_sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return_sync.js new file mode 100644 index 0000000000..7c222d3558 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/return_sync.js @@ -0,0 +1,24 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + // Note that this will throw on failure, which will fail the test. + var made = mkdirp.sync(file); + t.equal(made, '/tmp/' + x); + + // making the same file again should have no effect. + made = mkdirp.sync(file); + t.equal(made, null); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/root.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/root.js new file mode 100644 index 0000000000..97ad7a2f35 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/root.js @@ -0,0 +1,18 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('root', function (t) { + // '/' on unix, 'c:/' on windows. + var file = path.resolve('/'); + + mkdirp(file, 0755, function (err) { + if (err) throw err + fs.stat(file, function (er, stat) { + if (er) throw er + t.ok(stat.isDirectory(), 'target is a directory'); + t.end(); + }) + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/sync.js new file mode 100644 index 0000000000..88fa4324ee --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/sync.js @@ -0,0 +1,30 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('sync', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file, 0755); + } catch (err) { + t.fail(err); + return t.end(); + } + + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask.js new file mode 100644 index 0000000000..82c393a006 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask.js @@ -0,0 +1,26 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('implicit mode from umask', function (t) { + t.plan(5); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, 0777 & (~process.umask())); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }) + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask_sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask_sync.js new file mode 100644 index 0000000000..e537fbe4be --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkdirp/test/umask_sync.js @@ -0,0 +1,30 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; + +test('umask sync modes', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file); + } catch (err) { + t.fail(err); + return t.end(); + } + + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & 0777, (0777 & (~process.umask()))); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/.npmignore b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/.npmignore new file mode 100644 index 0000000000..c8f50f7cd3 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/.npmignore @@ -0,0 +1 @@ +npm-debug.log diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/LICENSE new file mode 100644 index 0000000000..45b6725d74 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/LICENSE @@ -0,0 +1,7 @@ +Copyright (C) 2012 Jonathan Rajavuori + +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. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/README.md b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/README.md new file mode 100644 index 0000000000..1a6b51dd20 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/README.md @@ -0,0 +1,27 @@ +# mkpath + +Make all directories in a path, like `mkdir -p`. + +## How to use + + var mkpath = require('mkpath'); + + mkpath('red/green/violet', function (err) { + if (err) throw err; + console.log('Directory structure red/green/violet created'); + }); + + mkpath.sync('/tmp/blue/orange', 0700); + +### mkpath(path, [mode = 0777 & (~process.umask()),] [callback]) + +Create all directories that don't exist in `path` with permissions `mode`. When finished, `callback(err)` fires with the error, if any. + +### mkpath.sync(path, [mode = 0777 & (~process.umask())]); + +Synchronous version of the same. Throws error, if any. + +## License + +This software is released under the [MIT license](http://www.opensource.org/licenses/MIT). + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/mkpath.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/mkpath.js new file mode 100644 index 0000000000..aa62f04060 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/mkpath.js @@ -0,0 +1,59 @@ +var fs = require('fs'); +var path = require('path'); + +var mkpath = function mkpath(dirpath, mode, callback) { + dirpath = path.resolve(dirpath); + + if (typeof mode === 'function' || typeof mode === 'undefined') { + callback = mode; + mode = 0777 & (~process.umask()); + } + + if (!callback) { + callback = function () {}; + } + + fs.stat(dirpath, function (err, stats) { + if (err) { + if (err.code === 'ENOENT') { + mkpath(path.dirname(dirpath), mode, function (err) { + if (err) { + callback(err); + } else { + fs.mkdir(dirpath, mode, callback); + } + }); + } else { + callback(err); + } + } else if (stats.isDirectory()) { + callback(null); + } else { + callback(new Error(dirpath + ' exists and is not a directory')); + } + }); +}; + +mkpath.sync = function mkpathsync(dirpath, mode) { + dirpath = path.resolve(dirpath); + + if (typeof mode === 'undefined') { + mode = 0777 & (~process.umask()); + } + + try { + if (!fs.statSync(dirpath).isDirectory()) { + throw new Error(dirpath + ' exists and is not a directory'); + } + } catch (err) { + if (err.code === 'ENOENT') { + mkpathsync(path.dirname(dirpath), mode); + fs.mkdirSync(dirpath, mode); + } else { + throw err; + } + } +}; + +module.exports = mkpath; + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/package.json new file mode 100644 index 0000000000..9224ba01bf --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/package.json @@ -0,0 +1,87 @@ +{ + "_args": [ + [ + { + "raw": "mkpath@^0.1.0", + "scope": null, + "escapedName": "mkpath", + "name": "mkpath", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/decompress-zip" + ] + ], + "_from": "mkpath@>=0.1.0 <0.2.0", + "_id": "mkpath@0.1.0", + "_inCache": true, + "_location": "/mkpath", + "_npmUser": { + "name": "jrajav", + "email": "jrajav@gmail.com" + }, + "_npmVersion": "1.1.65", + "_phantomChildren": {}, + "_requested": { + "raw": "mkpath@^0.1.0", + "scope": null, + "escapedName": "mkpath", + "name": "mkpath", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/decompress-zip" + ], + "_resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", + "_shasum": "7554a6f8d871834cc97b5462b122c4c124d6de91", + "_shrinkwrap": null, + "_spec": "mkpath@^0.1.0", + "_where": "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules/decompress-zip", + "author": { + "name": "Jonathan Rajavuori", + "email": "jrajav@gmail.com" + }, + "bugs": { + "url": "https://github.com/jrajav/mkpath/issues" + }, + "dependencies": {}, + "description": "Make all directories in a path, like mkdir -p", + "devDependencies": { + "tap": "~0.3" + }, + "directories": {}, + "dist": { + "shasum": "7554a6f8d871834cc97b5462b122c4c124d6de91", + "tarball": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz" + }, + "homepage": "https://github.com/jrajav/mkpath#readme", + "keywords": [ + "mkdir", + "mkdirp", + "directory", + "path", + "tree" + ], + "license": "MIT", + "main": "./mkpath", + "maintainers": [ + { + "name": "jrajav", + "email": "jrajav@gmail.com" + } + ], + "name": "mkpath", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jrajav/mkpath.git" + }, + "scripts": { + "test": "node node_modules/tap/bin/tap.js ./test" + }, + "version": "0.1.0" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/chmod.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/chmod.js new file mode 100644 index 0000000000..96d51bd3bc --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/chmod.js @@ -0,0 +1,42 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +test('chmod-pre', function (t) { + var mode = 0744 + mkpath(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.equal(stat && stat.mode & 0777, mode, 'should be 0744'); + t.end(); + }); + }); +}); + +test('chmod', function (t) { + var mode = 0755 + mkpath(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.end(); + }); + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/clobber.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/clobber.js new file mode 100644 index 0000000000..16d48ca104 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/clobber.js @@ -0,0 +1,41 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +// a file in the way +var itw = ps.slice(0, 3).join('/'); + + +test('clobber-pre', function (t) { + console.error("about to write to "+itw) + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); + + fs.stat(itw, function (er, stat) { + t.ifError(er) + t.ok(stat && stat.isFile(), 'should be file') + t.end() + }) +}) + +test('clobber', function (t) { + t.plan(2); + mkpath(file, 0755, function (err) { + t.ok(err); + t.equal(err.code, 'ENOTDIR'); + t.end(); + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/mkpath.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/mkpath.js new file mode 100644 index 0000000000..75cd4ec5e2 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/mkpath.js @@ -0,0 +1,32 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('woo', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkpath(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm.js new file mode 100644 index 0000000000..bb09d2024a --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm.js @@ -0,0 +1,36 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('async perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); + + mkpath(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + +test('async root perm', function (t) { + mkpath('/tmp', 0755, function (err) { + if (err) t.fail(err); + t.end(); + }); + t.end(); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm_sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm_sync.js new file mode 100644 index 0000000000..ee7f330c50 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/perm_sync.js @@ -0,0 +1,43 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; + + mkpath.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); + +test('sync root perm', function (t) { + t.plan(1); + + var file = '/tmp'; + mkpath.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/rel.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/rel.js new file mode 100644 index 0000000000..20ea10e46a --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/rel.js @@ -0,0 +1,36 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('rel', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkpath(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + process.chdir(cwd); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/root.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/root.js new file mode 100644 index 0000000000..78d4a027af --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/root.js @@ -0,0 +1,22 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('root', function (t) { + // '/' on unix, 'c:/' on windows. + var file = path.resolve('/'); + + mkpath(file, 0755, function (err) { + if (err) throw err + fs.stat(file, function (er, stat) { + if (er) throw er + t.ok(stat.isDirectory(), 'target is a directory'); + t.end(); + }) + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/sync.js new file mode 100644 index 0000000000..20fbc4739f --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/sync.js @@ -0,0 +1,36 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkpath.sync(file, 0755); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask.js new file mode 100644 index 0000000000..d2f8a71e6b --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask.js @@ -0,0 +1,32 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('implicit mode from umask', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkpath(file, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0777 & (~process.umask())); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask_sync.js b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask_sync.js new file mode 100644 index 0000000000..4b9e7ba739 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/mkpath/test/umask_sync.js @@ -0,0 +1,36 @@ +/* Tests borrowed from substack's node-mkdirp + * https://github.com/substack/node-mkdirp */ + +var mkpath = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('umask sync modes', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkpath.sync(file); + } catch (err) { + t.fail(err); + return t.end(); + } + + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, (0777 & (~process.umask()))); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }); + }); +}); + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/.npmignore b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/.npmignore new file mode 100644 index 0000000000..3c3629e647 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/LICENSE new file mode 100644 index 0000000000..04d21fe9b6 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Kuba Niegowski + +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. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/README.md b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/README.md new file mode 100644 index 0000000000..e218514c19 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/README.md @@ -0,0 +1,164 @@ +About +======== +Simple PNG encoder/decoder for Node.js with no native dependencies. + +Installation +=============== +``` +$ npm install node-png +``` + +Example +========== +```js +var fs = require('fs'), + PNG = require('pngjs').PNG; + +fs.createReadStream('in.png') + .pipe(new PNG({ + filterType: 4 + })) + .on('parsed', function() { + + for (var y = 0; y < this.height; y++) { + for (var x = 0; x < this.width; x++) { + var idx = (this.width * y + x) << 2; + + // invert color + this.data[idx] = 255 - this.data[idx]; + this.data[idx+1] = 255 - this.data[idx+1]; + this.data[idx+2] = 255 - this.data[idx+2]; + + // and reduce opacity + this.data[idx+3] = this.data[idx+3] >> 1; + } + } + + this.pack().pipe(fs.createWriteStream('out.png')); + }); +``` +For more examples see `examples` folder. + +Documentation +================ + +As input any color type is accepted (grayscale, rgb, palette, grayscale with alpha, rgb with alpha) but 8 bit per sample (channel) is the only supported bit depth. Interlaced mode is not supported. + +### Supported ancillary chunks +- `gAMA` - gamma, +- `tRNS` - transparency (but only for paletted image) + + +## Class: PNG +`PNG` is readable and writable `Stream`. + + +### Options +- `width` - use this with `height` if you want to create png from scratch +- `height` - as above +- `checkCRC` - whether parser should be strict about checksums in source stream (default: `true`) +- `deflateChunkSize` - chunk size used for deflating data chunks, this should be power of 2 and must not be less than 256 and more than 32*1024 (default: 32 kB) +- `deflateLevel` - compression level for delate (default: 9) +- `deflateStrategy` - compression strategy for delate (default: 3) +- `filterType` - png filtering method for scanlines (default: -1 => auto, accepts array of numbers 0-4) + + +### Event "metadata" +`function(metadata) { }` +Image's header has been parsed, metadata contains this information: +- `width` image size in pixels +- `height` image size in pixels +- `palette` image is paletted +- `color` image is not grayscale +- `alpha` image contains alpha channel + + +### Event: "parsed" +`function(data) { }` +Input image has been completly parsed, `data` is complete and ready for modification. + + +### Event: "error" +`function(error) { }` + + +### png.parse(data, [callback]) +Parses PNG file data. Alternatively you can stream data to instance of PNG. + +Optional `callback` is once called on `error` or `parsed`. The callback gets +two arguments `(err, data)`. + +Returns `this` for method chaining. + + +### png.pack() +Starts converting data to PNG file Stream. + +Returns `this` for method chaining. + + +### png.bitblt(dst, sx, sy, w, h, dx, dy) +Helper for image manipulation, copies rectangle of pixels from current image (`sx`, `sy`, `w`, `h`) to `dst` image (at `dx`, `dy`). + +Returns `this` for method chaining. + + +### Property: width +Width of image in pixels + + +### Property: height +Height of image in pixels + + +### Property: data +Buffer of image pixel data. Every pixel consists 4 bytes: R, G, B, A (opacity). + + +### Property: gamma +Gamma of image (0 if not specified) + +Changelog +============ + +### 0.4.0 - Jun 05 2013 + - fixed reading of destroyed input stream + +### 0.4.0-alpha - 29 Nov 2012 + - added zlib deflateStrategy option, default to Z_RLE (by pdpotter) + - added possibility to use multiple filters (by pdpotter, modified by niegowski) + +### 0.3.0-alpha - 23 Aug 2012 + - Processing data as Streams, not complete Buffers of data + +### 0.2.0-alpha - 21 Aug 2012 + - Input added palette, grayscale, no alpha support + - Better scanline filter selection + +### 0.1.0-alpha - 19 Aug 2012 + - First version + +License +========= + +(The MIT License) + +Copyright (c) 2012 Kuba Niegowski + +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. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/fromdocs.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/fromdocs.js new file mode 100644 index 0000000000..e530e53111 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/fromdocs.js @@ -0,0 +1,26 @@ + +var fs = require('fs'), + PNG = require('pngjs').PNG; + +fs.createReadStream('in.png') + .pipe(new PNG({ + filterType: 4 + })) + .on('parsed', function() { + + for (var y = 0; y < this.height; y++) { + for (var x = 0; x < this.width; x++) { + var idx = (this.width * y + x) << 2; + + // invert color + this.data[idx] = 255 - this.data[idx]; + this.data[idx+1] = 255 - this.data[idx+1]; + this.data[idx+2] = 255 - this.data[idx+2]; + + // and reduce opacity + this.data[idx+3] = this.data[idx+3] >> 1; + } + } + + this.pack().pipe(fs.createWriteStream('out.png')); + }); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/simple.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/simple.js new file mode 100644 index 0000000000..9edaab6001 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/simple.js @@ -0,0 +1,30 @@ +#!/usr/bin/env node + +var fs = require('fs'), + PNG = require('../lib/png').PNG; + + +var png = new PNG({ + filterType: -1 + }), + src = fs.createReadStream(process.argv[2]), + dst = fs.createWriteStream(process.argv[3] || 'out.png'); + + +png.on('parsed', function() { + + for (var y = 0; y < png.height; y++) { + for (var x = 0; x < png.width; x++) { + var idx = (png.width * y + x) << 2; + + if (Math.abs(png.data[idx] - png.data[idx+1]) <= 1 + && Math.abs(png.data[idx+1] - png.data[idx+2]) <= 1) + png.data[idx] = png.data[idx+1] = png.data[idx+2]; + + } + } + + png.pack().pipe(dst); +}); + +src.pipe(png); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/bg.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/bg.js new file mode 100644 index 0000000000..d36ff79bc6 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/bg.js @@ -0,0 +1,27 @@ +#!/usr/bin/env node + +var fs = require('fs'), + PNG = require('pngjs').PNG; + + +var png = new PNG({ + width: 10, + height: 10, + filterType: -1 +}); + + +for (var y = 0; y < png.height; y++) { + for (var x = 0; x < png.width; x++) { + var idx = (png.width * y + x) << 2; + + var col = x < (png.width >> 1) ^ y < (png.height >> 1) ? 0xe5 : 0xff; + + png.data[idx ] = col; + png.data[idx+1] = col; + png.data[idx+2] = col; + png.data[idx+3] = 0xff; + } +} + +png.pack().pipe(fs.createWriteStream(__dirname + '/bg.png')); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/bg.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..b030229db0a4edd335512da859381d192e92aec4 GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4sd&0LhE&{2{=?70lkwo@=JXd% qJU%=wO^hKYn$A893JP+*WXy2Kj`PUe+TJ}t^$eb_elF{r5}E)nPaC%Y literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.LICENSE new file mode 100644 index 0000000000..8d4d1d0777 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.LICENSE @@ -0,0 +1,9 @@ +PngSuite +-------- + +Permission to use, copy, modify and distribute these images for any +purpose and without fee is hereby granted. + + +(c) Willem van Schaik, 1996, 2011 + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.README b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.README new file mode 100644 index 0000000000..94df6ccffa --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/PngSuite.README @@ -0,0 +1,25 @@ + PNGSUITE +---------------- + + testset for PNG-(de)coders + created by Willem van Schaik +------------------------------------ + +This is a collection of graphics images created to test the png applications +like viewers, converters and editors. All (as far as that is possible) +formats supported by the PNG standard are represented. + +The suite consists of the following files: + +- PngSuite.README - this file +- PngSuite.LICENSE - the PngSuite is freeware +- PngSuite.png - image with PngSuite logo +- PngSuite.tgz - archive of all PNG testfiles +- PngSuite.zip - same in .zip format for PCs + + +-------- + (c) Willem van Schaik + willem@schaik.com + Calgary, April 2011 + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn0g08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..23c82379a29ff4b99806bbbd2e2342c8fd97ee67 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW*PVOS+@4BLidG0>c;6;(>fePZ!6K ziaE(C2`UUC949vOu(I~>b7=nfE^nVuX&@tFa7u7Oddi~87#=p(p8gM~{{27yqy1T- hp#)Io!PL|g7KVVQ{|ZeX-G~HP;_2$=vd$@?2>|oDDeM3M literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..db5ad15865f56e48e4bae5b43661d2dbc4e847e3 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1SJ1Ryj={WSkfJR9T^zg78t&m77yfmc)B=- zRLpsM^&lsM0S}Wy>zj#xw-*UpyJ&w|_~YC|?Jc}4)(u=DKV%lXeNyXF;n2v$@6|4U rsD)ibtrx; literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn3p08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn3p08.png new file mode 100644 index 0000000000000000000000000000000000000000..0ddad07e5f5de86a61bf43d8b89e138d7f1ea8ad GIT binary patch literal 1286 zcmWks4NMkw7=KO>3}y1F=z>r=LEEca@LnZf*~BA0ROZ5~$d#4)lIa>n+tGAx#s~NCh;!h=Q?&7t5~~Lk>mL*|1x+L`Ivp6mn?kJ^kK$c6a~%|NrOteLPR)ru^*4 zh?oc>ipx)wHw!xP<||VqG2mh2yNQ1IZKr30Xr(I7PBXU z(o_;ftk^?X5O*qmM)+A^aUR*s!>r3PlcI=3mc_D63M-aHQVj83+hHDKi)~wG8A%eb zMRFVzAa0kL4aW(lxy(-(A3@r7{KRdCcI^9^ zBwSWlMY4uMp(p@%T`0C7K$rnonuoRmLY9xP#5bTx(RKJi zCYfG^*s^*-{Ro^e4Kgw{Dlmv)JpjQ5bKwF@CLI|%59=nhA>e#HJh5GNjRLr(&Jco- zL=roU($L^w70~)&xPh+uFV&-K!K0w3W-9Hy@g@HWXL3ML4|%5ULen8 zlT@|D2@;VI*iada4446_ptp_#Sul*Cx7Y6>PlSiq8TyN-q=y}cXZX&@20)p=ihIP{CfA$Z*4W@ zEr$zzJ<~t_(0G1&!T9U{_Iz>DPFy@Dgq4(i*+1}U*ZiG1m)32#<4sRFJ5!AP>yZ}L zzdq~5lB&|C6*=qgy?nj!is#SN$*Gwo6M?qJgKJtd1_tvb_xS3qJuRh&eH)f1f0J@< z)4uq(Z_li{H~+s=+3L-xjU7X)ZvEUC-CLA+t^7d7$jI)tsK~;c&XdnBOC5Txp}1)@ zusm-vWl2G`{dnN}K>pDE=;yi{rVB@Y3B-HrtGOePxNz#}j}FD`z3|nlwikX+ZZ56= zAY&lKTUG9w&2^VN89D}o5=^>%~&6ID5>`0fk%7K&zZcY&F#znJTW|E zB5&cFwM~ly35&;HdZq5*>W9rM<&V4Wr%mNt{B`@CxYpR8I;^7!?Tc=wu6t&Du2Ec< zKIiz-xXN3dttqGahAW20Qo6MzgSk7e_{!(?CKyw`*?j|NY=7wG%F`JaWZ(VOm8CUr z$$no_)1uMK%W6)nN!IrL6EB>puUj#i+1xg}<&qUPnY6#j4&NW^MpZNn{t+Cq+^l@L JEAySt{s-!kV`~5a literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn4a08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn4a08.png new file mode 100644 index 0000000000000000000000000000000000000000..3e13052201c9f8b90172ea2491b18d6d121c2786 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtq=#3k+XOiwE*eJzX3_ zD&{2rIe*{)W9ys@6GNprI`<_tn04&i_AxF_G>~EoF-$NKa6jCj#n!|2C_^IPFayJV XErr@6uUk(54Pfwe^>bP0l+XkK+-D@M literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn6a08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/basn6a08.png new file mode 100644 index 0000000000000000000000000000000000000000..e6087387639b9cefaaafb696e29a8bd910ee0680 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+U~W1%@xC#RK{Io-U3d z6?5KRGvsP8;BkAXo|56e@Vk8|OTXfgyGLCsWP@G=X#A1))wtQkXb@LjH|PH@<7U}X zR(Ix8Y%6~9Ml4|WGnG@SZHQ?Kc`Uubi9hC!9z&%<$E5#{7BHGEsCHnVVk5wElR+}T f%%Pr9`U69dg47%_{vAF*s~J39{an^LB{Ts5$SFGl literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f00n0g08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f00n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..45a007596753f6627224931755c073a3362be88c GIT binary patch literal 319 zcmV-F0l@x=P)N8=ISR z4CLwk<95#Vg>&ou?4IBK-OKf4I=h+Q-Yu4^`-jJ;=a<*F_w~o;*Jiu>-k0SMV?!`9 z1Vck`We6?}!N3q)7=l6z!b$|W5>ORnBHWgrk_!4FAm#v-gL4rOlDZRAQhFl5C-ouJ zT{shgf4PuS-IlHh@Hud2s6Ob305=7HTh$nC5#jVOMRm%l2)`fuP_1(!!tE!01i`Tg zNcxC^mI$IC_VFh;N<~=u^=Vc`@;_)KBFl?^KZrv^P&WiMLvUaSEP*Ak#4p5s%2-gQ R&b9ym002ovPDHLkV1h+qhR^^2 literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f00n2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f00n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..d6a1ffff62eb0f1f1dcdb4ba2b1d30473d3adacd GIT binary patch literal 2475 zcmV;c2~_rpP)?U-rY?$u*rt72`ovo0oe?&{1KL>xM~Y#u90Sg9~r!Sz+#Sj{c9e50PfZRGEo*w)Pbtvs@yM>}|;lb>|){8?VU$X<&d+5@K1;`QX#oR;Tvfz1^SHi*8x(G?U}F{Es^*Sb z?yhHBBioyJsG0AzQr*w44t96)d>1dBWzR+SX}o!zcWxm*$D}Px(ibIBN#@ctuE=6# zE?4Js?ReG{a6=(C74fxse4~U-3U^j;cNJT!xv!Q7>UpG*e`%uH%#*GBct7JEywJ(Z zUFbpT#Y?Y|Q7jacnB!jzYdu#65G_R>FM> z|5(98mHbmR->;=w&l3$i)x_>*o@?QSc3$e>=bh|5$-XnZagn-)Sd~FtYmEQKsBJOn zZ<^Sg#NBC(X0a`o@8+|891j%mP$4^t_}*L|EupILcm=yEdAge2wT##Ed;>pi;-zMO z*2124UhQCCC%-<)n`e0IBBJXJu{wkLx-q`PsI{8(gC=$+QBC8qES|_^S3XaT}}w+CiXS+s}|m9=gki4oxFXLcg`U4sv)}7 z5Zh@`_Zs7ejoLAj9yd`-Vow^cWU)7wSMzyo9KS4JUm>p-@vFJ~x`a0repA7lmHcNl z^;+Jl=j{gmtBH4-`E3ioYv;c^_i1FQ%wwfMBW;e-;Npfs)i$R!*R`c zPB-?@bcLzC%={_6KfdAfH@WO4D|N29#g}ih?lv3laQnC1^(|YzWBd0!f<-~8EF`Z8 z%c~>u`lwtVGi+52JL85n%^1^-AJX&y_Ys|^Iqnnw{0yIXko=U-|DDS&v+^^p`GPO^ zu&$R4*SNipyS`$}4YuQ{fb>jIdNw323QI~vS{{{G#pIV%`IWdKtQp?Y4gH`N+V(PM zA4l%z*n^yWn2-18KcHV_>2a2Kaph?SyIFINb$?^SMQ*>$U7xcB6BIEyAUzh8riG*# zVaXSf7Dna8G5G~mULH5B((Vgvq-7IrVdlKfk#BPBgAVp^P8!|B{dYnon1AP7VDVSh|_zuXE*g26wV%H|yHifMl;Q`$URg z3{-?AAX0nLlXGT zaOFk@x3Fd#Urp2o;f3%)_#qUC07MW{2vQhQ1XA=qQI0>XdLWYr)7pP_ag>{nPUV#8 zeA35R#avLz#pQf)B?CdOuHibsZGtCBc$0#zYMR;2sE1D!f+s1_{4SC|M$4 z7r|^1$`#?^Kcq|XNs?9|=^mMd{h48$KY}G=SUQPIJq%3eDj(MrbNv!-Sjx@6Vk6*8 zh06+e20WSY4uvmU_#HwSAp-d#I7WoVKcvT=lGK?}e2%0ol=MaY$qcR-#>x>~J%(#1 zvBtv<)49pV*NXYZ5;iU6PQZ}{X9irEa1Vti2i`pRoWeg^DC0%IErO5rgG9t9q6?(h zbCOyn#VaJOsy{z~8!}iwj9W&qaSXRjVv~nErt=*i_Y|{j3HJeZD;$I2%z|qe+zxm~ z!aEwi@xnh@C>{}b>Olu0qKIgP6swZdwGT(a<^kND!RRoyjo`au*glB|JUld=9X`HS z%%gzK3VQ||L*UGYD-UibJT7=A!Z!u}X;6v~n1}xpLTeTJL5ZCyR0r{xohOE~Ycx+y z!Jr*7}ydLECgRbrs@xwwpCiJ*O zErmUUc*V}%;k-JU*Cz5y5Bt2l4p=O(T4A%nZimAGrxPw0+-`V0@Ot6%!S9EnAP_(> zC_*6-4vR=cM57`W6RIlWaiM8K*CjHA97Nj5;pAv?BI!x|i;!%_01HyB7-U119oY`# zIg#(eSU21rc)alXFx!t}1*HKj3nmN%>%ypuU~3d_$FNt$kvNWPIH!vqny)aumqV{I z?;1y4eV zt0Pz+MSTogRqTwTE%AZS#fLQimFdSh^d$2>;;7RJ0m*Pr!)Qjb1u0foY_Qrf*nuo3 zvR!bvG17z4UQF;|vL92Ggn{6hAf63jQ5Z@D%cEEo!%He&i6gAxEnU1r^Y5A7!l8Sa zw=W?eq1osBp*e3oT(F zn8xH8e7M&4G?4Hw6NDMU0?7)=2H6gS0|qCIE|}a%@+1rdW*<`g7^uJ!Kxz=y5YofQ ph+uFOnK2AeVUH&a1UWh!{10y?{8}W9lf?i4002ovPDHLkV1fmblkETi literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f01n0g08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f01n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1107b4637642335b8ec7b8e1856dc0ba7dab70 GIT binary patch literal 321 zcmV-H0lxl;P)}T4b;N0E z3!a!0=lJ%5$Eg%oz?c7nM_Pz6fDfO-!!(E~0KEA*c%UmW2WDfu_({31E3v>N-{Hyc z!o4_%Y@;b2{kGgyCmt~K_ux)+Vvc)%F>XgE7N{D;Epg%*RfD)GPQ0RO5I3R|@2DEY z_29%Oss?dQ2JwUcSEewBLHsU3nZgtbQQmYZ7(-i7*cJ?I3zBU?bOg~6L`VDql~F8% T6Mw4;00000NkvXXu0mjfmy?8r literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f01n2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f01n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..26fee958ce7e62a59843205ad34f86a525718595 GIT binary patch literal 1180 zcmV;N1Y`S&P)Qj4`pI zFjkU)u{F?Akfo*B!a}174J9nsV(#3X+5PQ?pp&O~&o{|^n{V!Obi%NV*_mQj=dbpv zm_B(tFHYo4wlii|=dbiix4xT4UZ{eGTtw$J**>tSy6N}n|vqif78L&$byRK9f1$SzrLzUf{!*^r3k$774rXm_7!8f1Q2+ z=C=8j8BA;b>93ttmB!R4Gqr2#)Il4ngL#p|9QHl^o9+4V^!;`CWzciKaJiBz*2s-A z%Q~e~hNeLo)I~S+8N27*(|0^}KLTZc)b*DYt70WpQX@6;tlY_+JY<94KKc3jyKkHx zc~$=bes_90V0+^67$}#lCtg&T@Kv!ADxnb@aaQcaP8xdm`scunQ;gUj^(pYH(^C;! zNn5y!L|KC#`k`FGPq->y@fF|j4L>V%d?yTrfgi+0@98t($EU{=wvxAS)ubd$_PkV3 z!A+>5imOt?H8kTouFDPFK!bmL?KbeO)596d+rNC?VU*+1#52gCK!FJ=R8*lsgBd#N zFko=|Nq}~GkP6E2D88M@l8GXUm_!xTsfy-kVs>rq&*Z3{>ZqRPX`b1u2fF{_*^dDC$unBQ(Ew)&lzW^YzR^hz^JI^CidP9to*K@y zNDItSJ$~`R-vM{)Cyb~i-{XO3q;i~yCk82yJm$&k5=WK56seJ#sF9XvnK_+adK+*z zf5tFI)>7;!5IcJyUb1-f+PNSFERrJ@DN!XcC2FQ7s?jpdPCtJOaPPm$D2$0wv{X9^ zWaZ)t@yIozCq+^qMJ$rnCC-%0l&Qw=-{Go9xBkqiT4p;6#CFmU*E%r}BWWdJiJY-a zF^Vx6Z~f)!f}4M1bjGY@*ij%CA&7a#dtxL;QaWQsUcZ|{DNGZ!QmbmEH8z2;34}4U zEce==fUtrOcu$DLNKC}F#?F@|D_EgSluD^gm7PG?1j0Nt7TXI1ibI5i_qeUYM`9wZ zHAc+m{muoO$dyvD%1$6`0-+Ag%UwbcF5n#U_<-~Hh>wJXPsDV-gPixfkS9{*C=fP* zFb&F3UG{zuavL5Oa2^-&5ueTk!)M~U--S34D@TE_2?QJDp|V`eAXY9N+By{R372qb zf6pNl!i29J1;Qo}(jX4E_qp%Fz4^!GobzySIy|o?)B5V>_Wt4V>G|dL?fv8P>$@@5`4A$18fipC zj4{?)>#TR)dmloGF-Am6L9i(ZNIDP1wql`V1IXeb3GF@N^}7L$OLT?eW035 z>s-(z0SrY%YCz?nO#+xF1yoYnBznj5E`aJnr^KQQpxV+di7ue_plgdhP^rb}TH<8U z-_)#002ovPDHLkV1l$} BmFfTh literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f02n2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f02n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..e590f1234816946731c677d0b353e2db5a08d71b GIT binary patch literal 1729 zcmV;y20r-x*}n2M`}#}vjc?j3 z-?s05&wlVj`|(fh7r(S$|JMHaC;Q7^?O*?~d&{=IVSD>_5?Nc!ER3!g3n}x;oHDCS zE7M9tnNlW|No7L0po}Y{%BV7;)RZA*NEuWHlu$uIF{MyCN=M0+Oi>NpMWV~bQp%#T zpv)_?%8W9jOe<4Ly-ylf#ww|%3|Gvc5-LF-)9o>#n>V*ev}9aNS<tNOUgyIH` zG-q7aJ|<;Bs%p}n(NLyR>cV6>o0KtOR2fOBDK%kO8B8li!+3&t(p()kWp0LO#<-$= zOvf4WkAB#DDgP)1#^?QNplUNhH+K4K#)MH}M8lng?S#!1>#?oI+;=QHd&_Y* zvQ2ag-A04p0Z)8E@cI#Yj2@#AdWt&Kp)E8)6V#)Eh6mnu6Sfn!T5QC&9<$>3pR;Ah zn~`mxSA%AGv*B#jvEq6SSw}a}hv?(JmFIitK6;2Y(MP>%q^zct!qYa9w`0$dr1uwhW0Zhu#4`YC3A2lof%qhmB?1mex?MvA0uiC*F<|9wjtewjbMGY&*`j zoNYQ=i;4%x3bKm)ELbUlhe-cy&Q~LkkWkfBOvHTK5^pVU&KE8zqNF%!6-RN=jJt=f zyYIStuDcy|)=2IKN9FDBuxB>$Tlj7K4t|&RE`A?>fIq}HX*X$yq{F5)WCR(dJ%%60 zUobyOQYUH9nkJsLcn-IKTf$xH1ii7(+IyZFAaXuHLUf39$aL7GW-`)eOjt5$$&|Gk z7SC8bXKudx>~4AcfL#|Bg#}?=m=$J(8L0w9n3UeL9uLU|&_U86bQr0b)M$_5M@xoe zf}~Ds%Hl?G{lDey;l^hyT6)`NFITQS5g;L1KsJC5kPe`O$dJh}?HYch$0Xw<6ZZU{ zd$-?t0XK_VuxLS_2oUXUsK?Ay2?S&T8dk=j$q?;fe2=lO{-L*jZof!e$2D-%xH*gF z^n8Gvsp5t2h@l@X8zXow7$3|f20{E)r!yT=R8p8tOF$?p``zg4{drQ+FJ#q^ho zXy)BBQMAcvVzRW z3^h_v5Ric9p5w+1ZrERCgI8Y-UVAOLeLHyLjo{85+yt&}QC+$AHbz)d7DMt5 zd6zUtb0njk;WJuFoZ^&7I1!H8G(892_Pp&Rww>5!%hqFCjqSd(WoK`>;%;>AP46PR z$UY&RE}af}mn)!IyrepUKyIwR{8>j(~{{02>UU6F*}Ye$EIT~(g*w> XLp~IzS7kjt00000NkvXXu0mjfY;#J> literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f03n0g08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f03n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..ed01e2923c92fd8b8786524c6d6841365a44b9de GIT binary patch literal 389 zcmV;00eb$4P)4Zd45D^U_MS@TiGz2aVLCXUNp&Fi;&<&!6t`aRYNwm-e(L$HR7llUs_2v2Lp?04i2#w>5 zCjFHgoS}>OqWhKs;-;4%0XoyCYd;H{ChLTAkL z`Nnmc1cXl84@#vy84@~$6^JKJlZ=Ubk`d9uF>y~YB0kwMamU0Lt#&uLFSbqGG0ztr z+6kZrX%qLj_#)n+{rCF=MU%cN0ReDq=R?P^VtFOGwjP)u6|4v*CxG_LFwq4OLVH6N jD*7N)_#jLSK#2GUV`p4Ky#5P000000NkvXXu0mjfx;dtp literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f03n2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f03n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..758115059d78260f7485521b83a864d4a930be84 GIT binary patch literal 1291 zcmV+m1@!ufP)=&S9{TIAi*MDSax9$V&z4Gt?ul6?wozPIOm-?GqbzHVVL0@-rxKGKhOL8k5O_q zSFpv3t*o}I*V_9Zvg_8{M;@~qp0pb`*{3(#=eF8yFWQ%0wy%ua*LT{9H|_38yXP&t z_Z_?MUHjhq_P_`B;30eDsQu(qd+fM9al)Sb+AZ}0v>o^z(58vARqwd=u@6n@Pmke1XD_3x{N{!lS^S@Mz)_} zdJOa7^M*h)z+aJKlpUap>FUU*babUGt;6i!o}sK%&_Ml_0}Q1o&Mu`O$?Cq66Q@JT z3RxIYM!*w1@Du|XA%l7Q)eI$}3>DD;e|4H6l$4TCgo02|@B=KrQ z@Wkm5Gr226kv_(nB^X7=$b&B_9m1$G>KKWRgkdJ$$Rs9|g_2{8Ez5|#T1H2TVa9h$ z(j;+7%SwO->aXp@3<>@U&;J{qzZIUl8J_zyJbOJn`+IoiYIx>K`1Q0sy`|S$qy4Ql z0v=}L_DlonP=h(73bQba+*O)>Gz;H^EtdX#W}j_9D|OAoJhWjRA~5T>Ndu`v9p<2x zV$3LYKl;cP4%*<5UG=dYJ8U03Vjuo4ycMs0P50HI0S#zE(=pl(GY{sz&C+xa)e;>z z1~aNPzjM$1t-?9LR-*64P#mG-1*D8@fZ(*yqnYop#)_J&`RW&@^-8p-T}(?iQxc|RDc*( z<`4s3eE1|ejyabvT}B)cWe8L&9Y4_UCg9tx=>U_B7``SQ&NPmDBN;&XQlhP3n_*jascABYwWa1geh;>x-+i4(U_Y8$pQBrmp@_v#) zgF2F8aQOzn)E_eOLYJ|y`CQzx3-$nmLD=V&A(sP5g05dja_!i}_ zgIDirr|I{mZhX~}7YtBA6@@6ph=h6QI6&Kt{O(YUr$lPFM|Gd{aIa#L7cd2c1x1(E z(Q=Gs10<^TF-)&&>U0cv)zz`6SBo;LJ%(}H?`NdF>L`))0fxOAVsvH`hUsg)nABw~ zucMi=tL~(v8Fzi|4FCoh!(J`gSItz-2XxH%{{y9tm%W$Hmi_<$002ovPDHLkV1gMt BbC>`C literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f04n0g08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f04n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..663fdae3e7d906df7379d92621a7a951313705cc GIT binary patch literal 269 zcmV+o0rLKdP){e2x4DAd1)!+NJ)f5B{T9psOdMM) z%F+|8FY)0+3~^>3vs1_&)hG|SqQp{zQhWvt^p*^yfsjOBNTM$!(HFu%2m|o|7A8yw TA(>!-00000NkvXXu0mjf-K%M) literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f04n2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/f04n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..3c8b5116e72a63a3de8e0c1892c147071d0269e7 GIT binary patch literal 985 zcmV;~119{5P)hvyJ!8utT1VEc>UN*1Tj!qJPN}IY>N=sRACLdrt)_N=Jy&nmRP0foi1T3q z1vs!^NS8tnTiC(|3Cm|k`D(`N4+4W;;{3xH5HR3=UuuoS4K!$rOa`(R z?R*&X`GvfR1n&u#ACUWVNrjF@+CUA>kh2DD{mP;k>FRtL8*-Oa0-8az@Zi?_D?6u0xgjeiedR*>(yJr`MN%ucekr3 zWi?2)HMNKXi#p_|&$f}^7s7eRdN|{jt0Vw}4uOnAlX>OyYx{;(h32S_hezhCE(Fab znDm|v`WGp9zt{od@3wLWe5y}twl%v9eNEpS4jt=K5jm_s#Yobzz%^iBf5O6mQ4IVB z1gSS#SEq}Q@Y^iry7D|7u$1$9vV7%>V~{k^6C{`$4zP=FjwZm`$rGS zvDv1V?}l%U4QyZyYY4D{53qy=jUGER5T*mg4DDFWy$X8(2FG?szK8L%=^pMOKo~6M z$j~Pc+wCNgX-nw*aZjf2VMtF87IxrAsgQ{`|D+q<6)@}&$53fBJv+1hHpj`E}Y00000NkvXX Hu0mjft5eU! literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tbrn2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tbrn2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..5cca0d621047cacf1637cf7d77e997d51cc6b15a GIT binary patch literal 1633 zcmV-n2A=teP))6_}Akuqmh*5X4X^rIbM;BH-v?$kU01p_ErCl=u4~ zL7fbz&H-~9!(}3aFu`RZW&unzb50QkgK2!RYsr=o3t~2tT^d3tzx&+X@9uj)%)Vj6 z{|IpB&Yj-g-pR?y{}^!Z-o3WAwzRagh=_<-fB!T`$I~7jJzDL9k&%A|7#|<+>gvkP z&5eqRQiO&cb#=`%Gt&SnAO*+-su`xq!J$j392p#Z_UzeG0aH^`SFc_zD=UkSkAGjG zNZGY3d;R({hG_tbfDeIqE;r1MUWVZftDkNW!h zs;jG$lamt?5{`w2W;;5Ta5(kAS>OWD3k(34fhLB@x3Eyz+ozkGX8`3uA)t^*Vq;_J zARVu%si6?50P_I-{r&0b>GXAy-pZYvJ_kMn+JSRiZt1pd#bWVg8=D~(>oza}`~v)> zM}7e)8HRFA`iDhFM^mix0K>z>DwQfHCnqyAGc`3;6%f#2ZhqFvO5^8uBq=H7FUwFU zT6XLhvbG*uwdz+cchJo2l$~8_P|)B15EmC05)$I?@88+kIS+9E{(W+tk&&UwQ56&v z(A`o(AH0rH_Tk~-0RaJGvDnww_wL=h^8j=?>6z)a6}IeCY}aO2b*Z|fq@=L0@WhD| zsSDdty^(jSiA*M&bM5WzEtks;bWvVj9&?GoHDC(zc6o7eG4)bKMMY_8X?Aw@u?6h# z;lshf`|a#hY<3Bkd&JHz$kWs3`0?Wg0OXPTF&CY{G^|Igi;9ZKH36!ss;DvOr&_J1 zx~1t&sZ>(M4;(lkk?c1!`x@w{b_L!AqU`OZt*xyF0OXE$lBa8(+d4*aQ!-UaQ=##! z_w+pDSx{e4UteEaTT3@Y0IErFaIj1kyl&n1z;8e!i?yF&L_nC8m3(Mu$N-?Zxp_n7 z2DAX*=>Wn$A?4)L>VvOzv*1+iR99Em(9l2wMRh0dROro{PXe>RH6x>UEG*vQa@TOV zQlU`t^yyOrfcExwL7@Om)cL>za2|4U%W^%=c<5%V3NB?X6h0+EjKsu5@-7xf85_?~ z_(n!?E-s$Cckkx$Tm=FtNq~V#ChO_xan5qaMSv9N2jF-3*7yqRh3Ek)Au1KoO;8fV zprIvzKyXeU{%KoVxrc`zkCz5CFib&h?McIcn>TN|Dcy8{RDkAq5^L3Kg|$LmUsXU< zBBJ4(W03sGWO5UeaSET!R&3c4%;9JOl9gkorlAz5VF1mVSE84$J}Q`0nqU|>1Di@4 ze5+F&_hR?T%1UBTp~Aw#cJ55qhku#R59RT^^+74-!fSSE~<7VgEJh?uUa0qm; z8Ez47t52=QkANEJ0t(=x^_iQy^73*TT0XxG7zGZwyYCSQ1YB+maEUU=$|_zAke{D# zTyIS3>>TO5U9}y3y6WrNG#}mt-ZU1(ApHmo3|zUggX&{s6zS#V<>Yh_y5_4hF$wDK z?p_S=`P`~WeyGw#>B+X26iZPz^D41kPE3=O0g4z6qf*N)=*PsGE4-+(Dp2{ zw2Zxeeeh*hh5=+_V`EuaSwV3@IIpj54kWn}jYdNZ8e`JrO`E(~ENUAnPWZ-+iMMY3 zY|zhwfLVQ0wY0S8#Df-Q7G&8n5<6nh7)vA)kx0bn+nAbqczMM?d^oX?lf?jYc4O#< zON|S4tujMN`;Hh?Jz7|PetuiGZY4pbYg^pItKUTv6B8tGw0Wp##Go?l literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n0g08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..333465fcdc9f10f7f25b2d999b558f5421983ecc GIT binary patch literal 719 zcmV;=0xe{x-64Dw5ISbDJfGPNXYF1fsnx~?7~M3eMD*m6rOMo0;2$rUW>-c(^**S*Ycd0zuX+u!1|S9WB+#F78QX<>lo? ziQz$h-hRnIWoQ!H=elq>2fX`s$g4Md}>$Ugu1e*ygBpcmqZ3DNb_5HNEsBtg8Fz$MsRgsRcUEt!R)#7 z@*=Hdg|%Ijgaqfp6x>M8@W|(*DezA>78ATBV zGiJ?6^pq7`pj8TmNNXtGQ7M(fr#kNOGpUKtO+a# zE}lAlTDXoRkAt?j2v0jgK~H>oU`AO)UQprWsr_L}qI~YALPA1E5ej}SPEJnGOv?!@ zojAEOR7Ob9QdC4?8%mP9keiy8ksVOlKd~`Xk)KCEK=mA2ntaoimYx|<+}mFjqR+?8 zZTJ8q(f(PLp6*}V-CGiDD=qBv7F)8vQWR0&(VZLQZ(jZjd%k$Tpt-FhJuqOwUu^jT z1pXapZA%Q=jx2U BP!RwC literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n2c08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..fc6e42cb420fd08ecd78340256157fa5f8a22934 GIT binary patch literal 1594 zcmV-A2F3Y_P)u542F>)wJ;-zU<0Ta5X4X^rIbM; zBH-v?$kU01p_ErCl=u4~L7fbz&H-~9!(}3aFu`RZW&unzb50QkgK2zirzKlPEQpyV zJ88Z&UwhB*+;h+QpNot)Z1^7mZr{G$*Vi{SHT9YSckkY9Z*NaePmhd@j0*@zcXT}E z>DjB%+#enNPk@PuiSF+1yu7^V=xBLZ*b!IPd^0mOpafEZETD#AngxPxg<^DQ=;_m^ zO9f0%PhYumrM$d6AtB*?xjc2}&YX4Y${D5+CG4W_vSdOD(DVN&-oB_@QeZU}a320`R0!vG! zgF}Y7c_vT+6ajLvI4&-Z7Si(C+FA;c5-<-iFfc$*`Z-x=6;4i{1D^pMz*&|p+q$(x zB)Vj4J8WQZ3z!6c0e;dUzW@{rLwimBm&L@yP^|L+BO@b9r7|}+H!CYEEiFwM7}#lU ze#Y8b?eBj$IXU%j%aqGow{IV|u^C^v@>iA}GBZ1AZ=V(%{LdfavLmWItxn1d>CixU>w z(z&H&q%@~cmeiGMuLdu#(_V!Qg$)f2b#--gLIj|kgoK1hr6FtAeh>TxG#MD|V;DCe z+}c_;JUpxi(9+VfzG^*Mf$y{cVZV^}t ze*#wx4d1b}e2ZmQv#dlY6hC?LL=T{&qk~_>M>ADEa39m2fL{qvo7rko-xdG82;t3ZKJ~Z{8fjKg!o$ON?8wlCe~HHnv#{{d1tq7Cl~vHp z%#3~jNv`NUkyhKvAxIVA8=wbFDWm}$)k06v92)E2}b{Rj#QTCt*&@?&Ti zD zl4Z+2B9B~dgtK!fhf@n&;PLjfw||-Og6SEVLqkKcv9UCP1w{gUs+$RUkfbMoF`VR)x@ASCQaVB z(Z|4m%7&5?v0+2f&6_{#^|K%#LswL-t*u(|pn;hUX^xb{ju_O&VzJoG&5g&iH8u70 z_D*>4U~(ZRivi~B`tWs^S{JHXMW%x09Wf|-G_d^r{kLq{LV`-iwz!9v--{+ECrRLF z@=(%OV07*qoM6N<$f`h#14gdfE literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n3p08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp0n3p08.png new file mode 100644 index 0000000000000000000000000000000000000000..69a69e5872234d96cab4cbb017a0933fbfedba81 GIT binary patch literal 1476 zcmWlXc~H^`6vv-Om}J3dn5OOMOgg5aIm=3#R_~R8*9gm+#ueDlIJqsFg@0;tH{|b8}HqQ5Jw$Ebasl zi9{wQqx{s={QP`?_T1du%K+m5+1c6W&Yc6O&&;#KYi za0xyG{0*U@p&=n5OeT{~rxS7s!NI{ht9Awk26}jqu-LA432IQH$P*->1%a<=E7fhf7KmpiNEL?|$g$1|@ z&=;ZU0fm$KWEP7BFz+mN_CD$D>KXyBfJUPQ1qHz$U@Noz`t>V3 z0Y5*#_4Rf5=AAr|%l))v3zbTRZXmD;`udA>dIa18XhRr(3s9%iK@&&<11kswKn|(| zCKfuzi4TRu*jp4GWDgcp#{666_U|?<$;@lL6fyrT=v@~MF43;U zZ$6b_)kkb?TQRlFx@L1DFHuvCdiGRV@qSb5o3SyX=dqWIo~SD}lgtU8-0hinIc|l^ zwZpyIy{+Kp3qku~jyuQS{wOJTffqk}ylg!rGf@@8WYp~qRTEe@i_6M#f}U2WR@4MfM)1HJRjPCMx~ z7uM(-p3*y>&A)fhi1A3;cS(L+J1;&pqWL&it>CX0-+eBqO{=g-lKzNGvG(`sNqtRF zeg3%mDzvL|F3Eho_0DyETn8H%dc!?dA!#0>Q=Vr9#{-Ga&|1#6CAW+Q0sfY$`N-&; z^0c=#@%4)8jy6X3lL6u3JAW=?c#tm>K2a$#(Q?|Uz}T^+pWADD@MB|q8>&Xr948aj zsY1|Z7&ad@u4wr4W%TE{WS7U&Rh^yI#(OsCtq$vQ3|A*M_uLm%-A~M)I@BiVUyS#YR$&g!`CNx58tIE z|3D@=NLJY$Q%;J12ZU?1w#&^2c5EzDN05DZLoa2szJ*SEwwg0|Mem<$Yn1cWcz^cq z-}lxrB6iz%k1R&3=>`|KS%};k)l(YskH!jI!g#-(&O>3hx)5(GX8X3fe_&q16?&Zr z)72bEymR&OySDOI3mZ0C3tSEiO=8X3u^BG}uBukDWrMyZ$LQ%Y4sr7@il=hRi%!IK N0G~qvls0mN@PBi2fm#3n literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp1n3p08.png b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/img/tp1n3p08.png new file mode 100644 index 0000000000000000000000000000000000000000..a6c9f35a86271c056e955f637a8769381eb03827 GIT binary patch literal 1483 zcmWlXdpOez7{_0ijw~Xj6ZLfH5mEEBP|@KrEtkTuS}m>SI;>1?8{6D(v$V!$$}kk^ z;zXQM92O%H=ShmnbXw(ZQ8_r3^Xq+{_x=9)zVGMz<@$KL>7tBL0HEvPj`Ks*k)Uu?Q@xn6z>Z3lMM-Q#6tfUZ$jg9xOySS8oYSdsZ?58S}Ku90Gh5`xl#{MR8%wt zP*_-43Lq2;*RS7_pPzr}(xrd%E)}>Vg+~H{0|EmB;S209 z+JEZQsgoy9!bij)vJ2CNNF)M$vKCsqg}Grc6c_?OKR+KIALs+qBGU~U&cS2w^z{7x z{X6{3T?w5=n_Ror-Q69U!8X)ZUHvP8K!G~|wFu*%2C7slr~p15FS4}-9)W zgA1TkDj@~(fB8jCjUG%S0R(${)B5}SM@HTPu)4duH*Un5nj+Sda5!dbYwOg=2pWA9 zg`xngv~oCl+wa{*R;b1Lc@x0-<4`CPvRn@w_UQh+Ac}Mk^OKb>f7-E19*W;}xs}~! zRlIciNyF__FM9f7*5I)-+cbPa1|k-TrQvsONlsb*)pnz$h0|UcNA3@z)MNfwE}Uv0 zIbFH+_Zk14HEp3y&g@1-ft^E-J#CK+WhE5TXruYlt&^-N^P3g#I=H!w`R}L=sT9s{ zCuD1uhCdG)aY*zhVd3F}HZMyY{g2C62iLwz8h1Q_?PFhSvbid>^O4P?YqRlh((eZd z#_aspCH=EBx%*CRO=qIG-J;L_AlZKBgiu)@&Tb|Ii=AapW?Zqp>gYA)sH#J5XB+h; zk9wYVqsyC_bvIrV9&w7WX>VWUAVpP~na{j&$UYNXX^m&}Uyx5RnnjA&4L3VdD!1H_ zD#Iq{ZueA8l;TIb`kpn$X5SsBHj?FpV!HrYcY~@^RN}pDGk;X^V&G~0qorYaOP*rv z^qN~4t3n!C(Ta6lUVkRto3S5$_!4xZm;=Uxwl-UlXk<^TD! zwrXx-kZ%7r>OqrnxrwlgbC>i*G{g?VCRx6GHc+-!v-|w+aMq(Z)3<$!sgDrNgW zt{66;txYft&kQV}Qtm74k`-qO{C2WMU5|#0wUn?oyC~|ghKx56YPk5`Xp_O#x8g2M X(5+n&l!#upArS?SL*BSr7fRay;V71Q literal 0 HcmV?d00001 diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/list.html b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/list.html new file mode 100644 index 0000000000..b2183fd2af --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/list.html @@ -0,0 +1,38 @@ + + + + PNG Test + + + +

Basic

+ grayscale
+ color
+ paletted
+ grayscale + alpha
+ color + alpha
+ +

Image filtering

+ grayscale, filter 0
+ color, filter 0
+ grayscale, filter 1
+ color, filter 1
+ grayscale, filter 2
+ color, filter 2
+ grayscale, filter 3
+ color, filter 3
+ grayscale, filter 4
+ color, filter 4
+ +

Transparency

+ grayscale, not transparent
+ color, not transparent
+ paletted, not transparent
+ color, transparent
+ paletted, transparent
+ + diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/out/.npmignore b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/out/.npmignore new file mode 100644 index 0000000000..e33609d251 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/out/.npmignore @@ -0,0 +1 @@ +*.png diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/test.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/test.js new file mode 100644 index 0000000000..1a9f6a1531 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/examples/test/test.js @@ -0,0 +1,38 @@ + +var fs = require('fs'), + PNG = require('pngjs').PNG; + + +fs.readdir(__dirname + '/img/', function(err, files) { + if (err) throw err; + + files.forEach(function(file) { + + if (!file.match(/\.png$/i)) + return; + + fs.createReadStream(__dirname + '/img/' + file) + .pipe(new PNG()) + .on('parsed', function() { + + if (this.gamma) { + for (var y = 0; y < this.height; y++) { + for (var x = 0; x < this.width; x++) { + var idx = (this.width * y + x) << 2; + + for (var i = 0; i < 3; i++) { + var sample = this.data[idx + i] / 255; + sample = Math.pow(sample, 1 / 2.2 / this.gamma); + this.data[idx + i] = Math.round(sample * 255); + } + } + } + } + + this.pack() + .pipe(fs.createWriteStream(__dirname + '/out/' + file)); + + }); + + }); +}); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/chunkstream.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/chunkstream.js new file mode 100644 index 0000000000..e57c1e7680 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/chunkstream.js @@ -0,0 +1,200 @@ +// Copyright (c) 2012 Kuba Niegowski +// +// 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. + +'use strict'; + + +var util = require('util'), + Stream = require('stream'); + + +var ChunkStream = module.exports = function() { + Stream.call(this); + + this._buffers = []; + this._buffered = 0; + + this._reads = []; + this._paused = false; + + this._encoding = 'utf8'; + this.writable = true; +}; +util.inherits(ChunkStream, Stream); + + +ChunkStream.prototype.read = function(length, callback) { + + this._reads.push({ + length: Math.abs(length), // if length < 0 then at most this length + allowLess: length < 0, + func: callback + }); + + process.nextTick(function() { + this._process(); + + // its paused and there is not enought data then ask for more + if (this._paused && this._reads.length > 0) { + this._paused = false; + + this.emit('drain'); + } + }.bind(this)); +}; + +ChunkStream.prototype.write = function(data, encoding) { + + if (!this.writable) { + this.emit('error', new Error('Stream not writable')); + return false; + } + + if (!Buffer.isBuffer(data)) + data = new Buffer(data, encoding || this._encoding); + + this._buffers.push(data); + this._buffered += data.length; + + this._process(); + + // ok if there are no more read requests + if (this._reads && this._reads.length == 0) + this._paused = true; + + return this.writable && !this._paused; +}; + +ChunkStream.prototype.end = function(data, encoding) { + + if (data) this.write(data, encoding); + + this.writable = false; + + // already destroyed + if (!this._buffers) return; + + // enqueue or handle end + if (this._buffers.length == 0) { + this._end(); + } else { + this._buffers.push(null); + this._process(); + } +}; + +ChunkStream.prototype.destroySoon = ChunkStream.prototype.end; + +ChunkStream.prototype._end = function() { + + if (this._reads.length > 0) { + this.emit('error', + new Error('There are some read requests waitng on finished stream') + ); + } + + this.destroy(); +}; + +ChunkStream.prototype.destroy = function() { + + if (!this._buffers) return; + + this.writable = false; + this._reads = null; + this._buffers = null; + + this.emit('close'); +}; + +ChunkStream.prototype._process = function() { + + // as long as there is any data and read requests + while (this._buffered > 0 && this._reads && this._reads.length > 0) { + + var read = this._reads[0]; + + // read any data (but no more than length) + if (read.allowLess) { + + // ok there is any data so that we can satisfy this request + this._reads.shift(); // == read + + // first we need to peek into first buffer + var buf = this._buffers[0]; + + // ok there is more data than we need + if (buf.length > read.length) { + + this._buffered -= read.length; + this._buffers[0] = buf.slice(read.length); + + read.func.call(this, buf.slice(0, read.length)); + + } else { + // ok this is less than maximum length so use it all + this._buffered -= buf.length; + this._buffers.shift(); // == buf + + read.func.call(this, buf); + } + + } else if (this._buffered >= read.length) { + // ok we can meet some expectations + + this._reads.shift(); // == read + + var pos = 0, + count = 0, + data = new Buffer(read.length); + + // create buffer for all data + while (pos < read.length) { + + var buf = this._buffers[count++], + len = Math.min(buf.length, read.length - pos); + + buf.copy(data, pos, 0, len); + pos += len; + + // last buffer wasn't used all so just slice it and leave + if (len != buf.length) + this._buffers[--count] = buf.slice(len); + } + + // remove all used buffers + if (count > 0) + this._buffers.splice(0, count); + + this._buffered -= read.length; + + read.func.call(this, data); + + } else { + // not enought data to satisfy first request in queue + // so we need to wait for more + break; + } + } + + if (this._buffers && this._buffers.length > 0 && this._buffers[0] == null) { + this._end(); + } +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/constants.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/constants.js new file mode 100644 index 0000000000..1e74b790a2 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/constants.js @@ -0,0 +1,38 @@ +// Copyright (c) 2012 Kuba Niegowski +// +// 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. + +'use strict'; + + +module.exports = { + + PNG_SIGNATURE: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], + + TYPE_IHDR: 0x49484452, + TYPE_IEND: 0x49454e44, + TYPE_IDAT: 0x49444154, + TYPE_PLTE: 0x504c5445, + TYPE_tRNS: 0x74524e53, + TYPE_gAMA: 0x67414d41, + + COLOR_PALETTE: 1, + COLOR_COLOR: 2, + COLOR_ALPHA: 4 +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/crc.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/crc.js new file mode 100644 index 0000000000..a3ac042313 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/crc.js @@ -0,0 +1,79 @@ +// Copyright (c) 2012 Kuba Niegowski +// +// 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. + +'use strict'; + +var util = require('util'), + Stream = require('stream'); + + +var CrcStream = module.exports = function() { + Stream.call(this); + + this._crc = -1; + + this.writable = true; +}; +util.inherits(CrcStream, Stream); + + +CrcStream.prototype.write = function(data) { + + for (var i = 0; i < data.length; i++) { + this._crc = crcTable[(this._crc ^ data[i]) & 0xff] ^ (this._crc >>> 8); + } + return true; +}; + +CrcStream.prototype.end = function(data) { + if (data) this.write(data); + + this.emit('crc', this.crc32()); +}; + +CrcStream.prototype.crc32 = function() { + return this._crc ^ -1; +}; + + +CrcStream.crc32 = function(buf) { + + var crc = -1; + for (var i = 0; i < buf.length; i++) { + crc = crcTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8); + } + return crc ^ -1; +}; + + + +var crcTable = []; + +for (var i = 0; i < 256; i++) { + var c = i; + for (var j = 0; j < 8; j++) { + if (c & 1) { + c = 0xedb88320 ^ (c >>> 1); + } else { + c = c >>> 1; + } + } + crcTable[i] = c; +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/filter.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/filter.js new file mode 100644 index 0000000000..fbe60d22cc --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/filter.js @@ -0,0 +1,314 @@ +// Copyright (c) 2012 Kuba Niegowski +// +// 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. + +'use strict'; + +var util = require('util'), + zlib = require('zlib'), + ChunkStream = require('./chunkstream'); + + +var Filter = module.exports = function(width, height, Bpp, data, options) { + ChunkStream.call(this); + + this._width = width; + this._height = height; + this._Bpp = Bpp; + this._data = data; + this._options = options; + + this._line = 0; + + if (!('filterType' in options) || options.filterType == -1) { + options.filterType = [0, 1, 2, 3, 4]; + } else if (typeof options.filterType == 'number') { + options.filterType = [options.filterType]; + } + + this._filters = { + 0: this._filterNone.bind(this), + 1: this._filterSub.bind(this), + 2: this._filterUp.bind(this), + 3: this._filterAvg.bind(this), + 4: this._filterPaeth.bind(this) + }; + + this.read(this._width * Bpp + 1, this._reverseFilterLine.bind(this)); +}; +util.inherits(Filter, ChunkStream); + + +var pixelBppMap = { + 1: { // L + 0: 0, + 1: 0, + 2: 0, + 3: 0xff + }, + 2: { // LA + 0: 0, + 1: 0, + 2: 0, + 3: 1 + }, + 3: { // RGB + 0: 0, + 1: 1, + 2: 2, + 3: 0xff + }, + 4: { // RGBA + 0: 0, + 1: 1, + 2: 2, + 3: 3 + } +}; + +Filter.prototype._reverseFilterLine = function(rawData) { + + var pxData = this._data, + pxLineLength = this._width << 2, + pxRowPos = this._line * pxLineLength, + filter = rawData[0]; + + if (filter == 0) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i]; + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] : 0xff; + } + } + + } else if (filter == 1) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + left = x > 0 ? pxData[pxPos + i - 4] : 0; + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + left : 0xff; + } + } + + } else if (filter == 2) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + up = this._line > 0 ? pxData[pxPos - pxLineLength + i] : 0; + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + up : 0xff; + } + + } + + } else if (filter == 3) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + left = x > 0 ? pxData[pxPos + i - 4] : 0, + up = this._line > 0 ? pxData[pxPos - pxLineLength + i] : 0, + add = Math.floor((left + up) / 2); + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + add : 0xff; + } + + } + + } else if (filter == 4) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + left = x > 0 ? pxData[pxPos + i - 4] : 0, + up = this._line > 0 ? pxData[pxPos - pxLineLength + i] : 0, + upLeft = x > 0 && this._line > 0 + ? pxData[pxPos - pxLineLength + i - 4] : 0, + add = PaethPredictor(left, up, upLeft); + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + add : 0xff; + } + } + } + + + this._line++; + + if (this._line < this._height) + this.read(this._width * this._Bpp + 1, this._reverseFilterLine.bind(this)); + else + this.emit('complete', this._data, this._width, this._height); +}; + + + + +Filter.prototype.filter = function() { + + var pxData = this._data, + rawData = new Buffer(((this._width << 2) + 1) * this._height); + + for (var y = 0; y < this._height; y++) { + + // find best filter for this line (with lowest sum of values) + var filterTypes = this._options.filterType, + min = Infinity, + sel = 0; + + for (var i = 0; i < filterTypes.length; i++) { + var sum = this._filters[filterTypes[i]](pxData, y, null); + if (sum < min) { + sel = filterTypes[i]; + min = sum; + } + } + + this._filters[sel](pxData, y, rawData); + } + return rawData; +}; + +Filter.prototype._filterNone = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (!rawData) { + for (var x = 0; x < pxRowLength; x++) + sum += Math.abs(pxData[y * pxRowLength + x]); + + } else { + rawData[y * rawRowLength] = 0; + pxData.copy(rawData, rawRowLength * y + 1, pxRowLength * y, pxRowLength * (y + 1)); + } + + return sum; +}; + +Filter.prototype._filterSub = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 1; + + for (var x = 0; x < pxRowLength; x++) { + + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + val = pxData[y * pxRowLength + x] - left; + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + +Filter.prototype._filterUp = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 2; + + for (var x = 0; x < pxRowLength; x++) { + + var up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + val = pxData[y * pxRowLength + x] - up; + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + +Filter.prototype._filterAvg = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 3; + + for (var x = 0; x < pxRowLength; x++) { + + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + val = pxData[y * pxRowLength + x] - ((left + up) >> 1); + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + +Filter.prototype._filterPaeth = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 4; + + for (var x = 0; x < pxRowLength; x++) { + + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + upLeft = x >= 4 && y > 0 ? pxData[(y - 1) * pxRowLength + x - 4] : 0, + val = pxData[y * pxRowLength + x] - PaethPredictor(left, up, upLeft); + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + + + +var PaethPredictor = function(left, above, upLeft) { + + var p = left + above - upLeft, + pLeft = Math.abs(p - left), + pAbove = Math.abs(p - above), + pUpLeft = Math.abs(p - upLeft); + + if (pLeft <= pAbove && pLeft <= pUpLeft) return left; + else if (pAbove <= pUpLeft) return above; + else return upLeft; +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/packer.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/packer.js new file mode 100644 index 0000000000..d069448f5e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/packer.js @@ -0,0 +1,110 @@ +// Copyright (c) 2012 Kuba Niegowski +// +// 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. + +'use strict'; + + +var util = require('util'), + Stream = require('stream'), + zlib = require('zlib'), + Filter = require('./filter'), + CrcStream = require('./crc'), + constants = require('./constants'); + + +var Packer = module.exports = function(options) { + Stream.call(this); + + this._options = options; + + options.deflateChunkSize = options.deflateChunkSize || 32 * 1024; + options.deflateLevel = options.deflateLevel || 9; + options.deflateStrategy = options.deflateStrategy || 3; + + this.readable = true; +}; +util.inherits(Packer, Stream); + + +Packer.prototype.pack = function(data, width, height) { + + // Signature + this.emit('data', new Buffer(constants.PNG_SIGNATURE)); + this.emit('data', this._packIHDR(width, height)); + + // filter pixel data + var filter = new Filter(width, height, 4, data, this._options); + var data = filter.filter(); + + // compress it + var deflate = zlib.createDeflate({ + chunkSize: this._options.deflateChunkSize, + level: this._options.deflateLevel, + strategy: this._options.deflateStrategy + }); + deflate.on('error', this.emit.bind(this, 'error')); + + deflate.on('data', function(data) { + this.emit('data', this._packIDAT(data)); + }.bind(this)); + + deflate.on('end', function() { + this.emit('data', this._packIEND()); + this.emit('end'); + }.bind(this)); + + deflate.end(data); +}; + +Packer.prototype._packChunk = function(type, data) { + + var len = (data ? data.length : 0), + buf = new Buffer(len + 12); + + buf.writeUInt32BE(len, 0); + buf.writeUInt32BE(type, 4); + + if (data) data.copy(buf, 8); + + buf.writeInt32BE(CrcStream.crc32(buf.slice(4, buf.length - 4)), buf.length - 4); + return buf; +}; + +Packer.prototype._packIHDR = function(width, height) { + + var buf = new Buffer(13); + buf.writeUInt32BE(width, 0); + buf.writeUInt32BE(height, 4); + buf[8] = 8; + buf[9] = 6; // colorType + buf[10] = 0; // compression + buf[11] = 0; // filter + buf[12] = 0; // interlace + + return this._packChunk(constants.TYPE_IHDR, buf); +}; + +Packer.prototype._packIDAT = function(data) { + return this._packChunk(constants.TYPE_IDAT, data); +}; + +Packer.prototype._packIEND = function() { + return this._packChunk(constants.TYPE_IEND, null); +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/parser.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/parser.js new file mode 100644 index 0000000000..f4eef7b279 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/parser.js @@ -0,0 +1,359 @@ +// Copyright (c) 2012 Kuba Niegowski +// +// 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. + +'use strict'; + + +var util = require('util'), + zlib = require('zlib'), + CrcStream = require('./crc'), + ChunkStream = require('./chunkstream'), + constants = require('./constants'), + Filter = require('./filter'); + + +var Parser = module.exports = function(options) { + ChunkStream.call(this); + + this._options = options; + options.checkCRC = options.checkCRC !== false; + + this._hasIHDR = false; + this._hasIEND = false; + + this._inflate = null; + this._filter = null; + this._crc = null; + + // input flags/metadata + this._palette = []; + this._colorType = 0; + + this._chunks = {}; + this._chunks[constants.TYPE_IHDR] = this._handleIHDR.bind(this); + this._chunks[constants.TYPE_IEND] = this._handleIEND.bind(this); + this._chunks[constants.TYPE_IDAT] = this._handleIDAT.bind(this); + this._chunks[constants.TYPE_PLTE] = this._handlePLTE.bind(this); + this._chunks[constants.TYPE_tRNS] = this._handleTRNS.bind(this); + this._chunks[constants.TYPE_gAMA] = this._handleGAMA.bind(this); + + this.writable = true; + + this.on('error', this._handleError.bind(this)); + this._handleSignature(); +}; +util.inherits(Parser, ChunkStream); + + +Parser.prototype._handleError = function() { + + this.writable = false; + + this.destroy(); + + if (this._inflate) + this._inflate.destroy(); +}; + +Parser.prototype._handleSignature = function() { + this.read(constants.PNG_SIGNATURE.length, + this._parseSignature.bind(this) + ); +}; + +Parser.prototype._parseSignature = function(data) { + + var signature = constants.PNG_SIGNATURE; + + for (var i = 0; i < signature.length; i++) { + if (data[i] != signature[i]) { + this.emit('error', new Error('Invalid file signature')); + return; + } + } + this.read(8, this._parseChunkBegin.bind(this)); +}; + +Parser.prototype._parseChunkBegin = function(data) { + + // chunk content length + var length = data.readUInt32BE(0); + + // chunk type + var type = data.readUInt32BE(4), + name = ''; + for (var i = 4; i < 8; i++) + name += String.fromCharCode(data[i]); + + // console.log('chunk ', name, length); + + // chunk flags + var ancillary = !!(data[4] & 0x20), // or critical + priv = !!(data[5] & 0x20), // or public + safeToCopy = !!(data[7] & 0x20); // or unsafe + + if (!this._hasIHDR && type != constants.TYPE_IHDR) { + this.emit('error', new Error('Expected IHDR on beggining')); + return; + } + + this._crc = new CrcStream(); + this._crc.write(new Buffer(name)); + + if (this._chunks[type]) { + return this._chunks[type](length); + + } else if (!ancillary) { + this.emit('error', new Error('Unsupported critical chunk type ' + name)); + return; + } else { + this.read(length + 4, this._skipChunk.bind(this)); + } +}; + +Parser.prototype._skipChunk = function(data) { + this.read(8, this._parseChunkBegin.bind(this)); +}; + +Parser.prototype._handleChunkEnd = function() { + this.read(4, this._parseChunkEnd.bind(this)); +}; + +Parser.prototype._parseChunkEnd = function(data) { + + var fileCrc = data.readInt32BE(0), + calcCrc = this._crc.crc32(); + + // check CRC + if (this._options.checkCRC && calcCrc != fileCrc) { + this.emit('error', new Error('Crc error')); + return; + } + + if (this._hasIEND) { + this.destroySoon(); + + } else { + this.read(8, this._parseChunkBegin.bind(this)); + } +}; + + +Parser.prototype._handleIHDR = function(length) { + this.read(length, this._parseIHDR.bind(this)); +}; +Parser.prototype._parseIHDR = function(data) { + + this._crc.write(data); + + var width = data.readUInt32BE(0), + height = data.readUInt32BE(4), + depth = data[8], + colorType = data[9], // bits: 1 palette, 2 color, 4 alpha + compr = data[10], + filter = data[11], + interlace = data[12]; + + // console.log(' width', width, 'height', height, + // 'depth', depth, 'colorType', colorType, + // 'compr', compr, 'filter', filter, 'interlace', interlace + // ); + + if (depth != 8) { + this.emit('error', new Error('Unsupported bit depth ' + depth)); + return; + } + if (!(colorType in colorTypeToBppMap)) { + this.emit('error', new Error('Unsupported color type')); + return; + } + if (compr != 0) { + this.emit('error', new Error('Unsupported compression method')); + return; + } + if (filter != 0) { + this.emit('error', new Error('Unsupported filter method')); + return; + } + if (interlace != 0) { + this.emit('error', new Error('Unsupported interlace method')); + return; + } + + this._colorType = colorType; + + this._data = new Buffer(width * height * 4); + this._filter = new Filter( + width, height, + colorTypeToBppMap[this._colorType], + this._data, + this._options + ); + + this._hasIHDR = true; + + this.emit('metadata', { + width: width, + height: height, + palette: !!(colorType & constants.COLOR_PALETTE), + color: !!(colorType & constants.COLOR_COLOR), + alpha: !!(colorType & constants.COLOR_ALPHA), + data: this._data + }); + + this._handleChunkEnd(); +}; + + +Parser.prototype._handlePLTE = function(length) { + this.read(length, this._parsePLTE.bind(this)); +}; +Parser.prototype._parsePLTE = function(data) { + + this._crc.write(data); + + var entries = Math.floor(data.length / 3); + // console.log('Palette:', entries); + + for (var i = 0; i < entries; i++) { + this._palette.push([ + data.readUInt8(i * 3), + data.readUInt8(i * 3 + 1), + data.readUInt8(i * 3 + 2 ), + 0xff + ]); + } + + this._handleChunkEnd(); +}; + +Parser.prototype._handleTRNS = function(length) { + this.read(length, this._parseTRNS.bind(this)); +}; +Parser.prototype._parseTRNS = function(data) { + + this._crc.write(data); + + // palette + if (this._colorType == 3) { + if (this._palette.length == 0) { + this.emit('error', new Error('Transparency chunk must be after palette')); + return; + } + if (data.length > this._palette.length) { + this.emit('error', new Error('More transparent colors than palette size')); + return; + } + for (var i = 0; i < this._palette.length; i++) { + this._palette[i][3] = i < data.length ? data.readUInt8(i) : 0xff; + } + } + + // for colorType 0 (grayscale) and 2 (rgb) + // there might be one gray/color defined as transparent + + this._handleChunkEnd(); +}; + +Parser.prototype._handleGAMA = function(length) { + this.read(length, this._parseGAMA.bind(this)); +}; +Parser.prototype._parseGAMA = function(data) { + + this._crc.write(data); + this.emit('gamma', data.readUInt32BE(0) / 100000); + + this._handleChunkEnd(); +}; + +Parser.prototype._handleIDAT = function(length) { + this.read(-length, this._parseIDAT.bind(this, length)); +}; +Parser.prototype._parseIDAT = function(length, data) { + + this._crc.write(data); + + if (this._colorType == 3 && this._palette.length == 0) + throw new Error('Expected palette not found'); + + if (!this._inflate) { + this._inflate = zlib.createInflate(); + + this._inflate.on('error', this.emit.bind(this, 'error')); + this._filter.on('complete', this._reverseFiltered.bind(this)); + + this._inflate.pipe(this._filter); + } + + this._inflate.write(data); + length -= data.length; + + if (length > 0) + this._handleIDAT(length); + else + this._handleChunkEnd(); +}; + + +Parser.prototype._handleIEND = function(length) { + this.read(length, this._parseIEND.bind(this)); +}; +Parser.prototype._parseIEND = function(data) { + + this._crc.write(data); + + // no more data to inflate + this._inflate.end(); + + this._hasIEND = true; + this._handleChunkEnd(); +}; + + +var colorTypeToBppMap = { + 0: 1, + 2: 3, + 3: 1, + 4: 2, + 6: 4 +}; + +Parser.prototype._reverseFiltered = function(data, width, height) { + + if (this._colorType == 3) { // paletted + + // use values from palette + var pxLineLength = width << 2; + + for (var y = 0; y < height; y++) { + var pxRowPos = y * pxLineLength; + + for (var x = 0; x < width; x++) { + var pxPos = pxRowPos + (x << 2), + color = this._palette[data[pxPos]]; + + for (var i = 0; i < 4; i++) + data[pxPos + i] = color[i]; + } + } + } + + this.emit('parsed', data); +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/png.js b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/png.js new file mode 100644 index 0000000000..c2c56c9fbd --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/lib/png.js @@ -0,0 +1,149 @@ +// Copyright (c) 2012 Kuba Niegowski +// +// 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. + +'use strict'; + + +var util = require('util'), + Stream = require('stream'), + Parser = require('./parser'), + Packer = require('./packer'); + + +var PNG = exports.PNG = function(options) { + Stream.call(this); + + options = options || {}; + + this.width = options.width || 0; + this.height = options.height || 0; + + this.data = this.width > 0 && this.height > 0 + ? new Buffer(4 * this.width * this.height) : null; + + if(options.fill && this.data){this.data.fill(0)}; + + this.gamma = 0; + this.readable = this.writable = true; + + this._parser = new Parser(options || {}); + + this._parser.on('error', this.emit.bind(this, 'error')); + this._parser.on('close', this._handleClose.bind(this)); + this._parser.on('metadata', this._metadata.bind(this)); + this._parser.on('gamma', this._gamma.bind(this)); + this._parser.on('parsed', function(data) { + this.data = data; + this.emit('parsed', data); + }.bind(this)); + + this._packer = new Packer(options); + this._packer.on('data', this.emit.bind(this, 'data')); + this._packer.on('end', this.emit.bind(this, 'end')); + this._parser.on('close', this._handleClose.bind(this)); + this._packer.on('error', this.emit.bind(this, 'error')); + +}; +util.inherits(PNG, Stream); + + +PNG.prototype.pack = function() { + + process.nextTick(function() { + this._packer.pack(this.data, this.width, this.height); + }.bind(this)); + + return this; +}; + + +PNG.prototype.parse = function(data, callback) { + + if (callback) { + var onParsed = null, onError = null; + + this.once('parsed', onParsed = function(data) { + this.removeListener('error', onError); + + this.data = data; + callback(null, this); + + }.bind(this)); + + this.once('error', onError = function(err) { + this.removeListener('parsed', onParsed); + + callback(err, null); + }.bind(this)); + } + + this.end(data); + return this; +}; + +PNG.prototype.write = function(data) { + this._parser.write(data); + return true; +}; + +PNG.prototype.end = function(data) { + this._parser.end(data); +}; + +PNG.prototype._metadata = function(metadata) { + this.width = metadata.width; + this.height = metadata.height; + this.data = metadata.data; + + delete metadata.data; + this.emit('metadata', metadata); +}; + +PNG.prototype._gamma = function(gamma) { + this.gamma = gamma; +}; + +PNG.prototype._handleClose = function() { + if (!this._parser.writable && !this._packer.readable) + this.emit('close'); +}; + + +PNG.prototype.bitblt = function(dst, sx, sy, w, h, dx, dy) { + + var src = this; + + if (sx > src.width || sy > src.height + || sx + w > src.width || sy + h > src.height) + throw new Error('bitblt reading outside image'); + if (dx > dst.width || dy > dst.height + || dx + w > dst.width || dy + h > dst.height) + throw new Error('bitblt writing outside image'); + + for (var y = 0; y < h; y++) { + src.data.copy(dst.data, + ((dy + y) * dst.width + dx) << 2, + ((sy + y) * src.width + sx) << 2, + ((sy + y) * src.width + sx + w) << 2 + ); + } + + return this; +}; diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/package.json new file mode 100644 index 0000000000..c359bea33c --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/node-png/package.json @@ -0,0 +1,59 @@ +{ + "_args": [ + [ + "node-png@0.4.3", + "/private/var/lib/jenkins/workspace/iconik_panel/src" + ] + ], + "_from": "node-png@0.4.3", + "_id": "node-png@0.4.3", + "_inBundle": false, + "_integrity": "sha1-RQIjeWuC08yg/+Sl1cf6l0hZdOc=", + "_location": "/node-png", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "node-png@0.4.3", + "name": "node-png", + "escapedName": "node-png", + "rawSpec": "0.4.3", + "saveSpec": null, + "fetchSpec": "0.4.3" + }, + "_requiredBy": [ + "/imagejs" + ], + "_resolved": "https://registry.npmjs.org/node-png/-/node-png-0.4.3.tgz", + "_spec": "0.4.3", + "_where": "/private/var/lib/jenkins/workspace/iconik_panel/src", + "author": { + "name": "Kuba Niegowski" + }, + "bugs": { + "url": "https://github.com/brighthas/node-pngjs/issues" + }, + "contributors": [], + "description": "Simple PNG encoder/decoder", + "directories": { + "example": "examples" + }, + "engines": { + "node": "0.8.x" + }, + "homepage": "https://github.com/niegowski/node-pngjs/", + "keywords": [ + "png" + ], + "license": "MIT", + "main": "./lib/png.js", + "name": "node-png", + "repository": { + "type": "git", + "url": "git://github.com/brighthas/node-pngjs.git" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "version": "0.4.3" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintignore b/pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintignore new file mode 100644 index 0000000000..651665bbd9 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintignore @@ -0,0 +1,2 @@ +node_modules +.git diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintrc b/pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintrc new file mode 100644 index 0000000000..765fb34a1e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/.jshintrc @@ -0,0 +1,27 @@ +{ + "bitwise": true, + "curly": true, + "eqeqeq": true, + "forin": true, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": true, + "plusplus": false, + "regexp": false, + "undef": true, + "strict": false, + "trailing": true, + + "eqnull": true, + "laxcomma": true, + + "node": true, + + "onevar": true, + "white": true, + + "indent": 2 +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/.npmignore b/pype/premiere/extensions/com.pype.avalon/node_modules/open/.npmignore new file mode 100644 index 0000000000..9daeafb986 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/.npmignore @@ -0,0 +1 @@ +test diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/open/LICENSE new file mode 100644 index 0000000000..58b5cd2414 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 Jay Jordan + +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. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/README.md b/pype/premiere/extensions/com.pype.avalon/node_modules/open/README.md new file mode 100644 index 0000000000..4fc0d54ece --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/README.md @@ -0,0 +1,33 @@ +# open + +Open a file or url in the user's preferred application. + +# Usage + +```javascript +var open = require("open"); +open("http://www.google.com"); +``` + +`open` taks an optional argument specifying the program to be used to open the +file or URL. + +```javascript +open("http://www.google.com", "firefox"); +``` + +# Installation + + npm install open + +# How it works + +- on `win32` uses `start` +- on `darwin` uses `open` +- otherwise uses the `xdg-open` script from [freedesktop.org](http://portland.freedesktop.org/xdg-utils-1.0/xdg-open.html) + +# Warning + +The same care should be taken when calling open as if you were calling +[child_process.exec](http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) +directly. If it is an executable it will run in a new shell. diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/lib/open.js b/pype/premiere/extensions/com.pype.avalon/node_modules/open/lib/open.js new file mode 100644 index 0000000000..667bc175d7 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/lib/open.js @@ -0,0 +1,63 @@ +var exec = require('child_process').exec + , path = require('path') + ; + + +/** + * open a file or uri using the default application for the file type. + * + * @return {ChildProcess} - the child process object. + * @param {string} target - the file/uri to open. + * @param {string} appName - (optional) the application to be used to open the + * file (for example, "chrome", "firefox") + * @param {function(Error)} callback - called with null on success, or + * an error object that contains a property 'code' with the exit + * code of the process. + */ + +module.exports = open; + +function open(target, appName, callback) { + var opener; + + if (typeof(appName) === 'function') { + callback = appName; + appName = null; + } + + switch (process.platform) { + case 'darwin': + if (appName) { + opener = 'open -a "' + escape(appName) + '"'; + } else { + opener = 'open'; + } + break; + case 'win32': + // if the first parameter to start is quoted, it uses that as the title + // so we pass a blank title so we can quote the file we are opening + if (appName) { + opener = 'start "" "' + escape(appName) + '"'; + } else { + opener = 'start ""'; + } + break; + default: + if (appName) { + opener = escape(appName); + } else { + // use Portlands xdg-open everywhere else + opener = path.join(__dirname, '../vendor/xdg-open'); + } + break; + } + + if (process.env.SUDO_USER) { + opener = 'sudo -u ' + process.env.SUDO_USER + ' ' + opener; + } + return exec(opener + ' "' + escape(target) + '"', callback); +} + +function escape(s) { + return s.replace(/"/g, '\\\"'); +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/open/package.json new file mode 100644 index 0000000000..9dec20a1ea --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + { + "raw": "open", + "scope": null, + "escapedName": "open", + "name": "open", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules" + ] + ], + "_from": "open@latest", + "_id": "open@0.0.5", + "_inCache": true, + "_location": "/open", + "_npmUser": { + "name": "pwnall", + "email": "costan@gmail.com" + }, + "_npmVersion": "1.4.3", + "_phantomChildren": {}, + "_requested": { + "raw": "open", + "scope": null, + "escapedName": "open", + "name": "open", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER" + ], + "_resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz", + "_shasum": "42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc", + "_shrinkwrap": null, + "_spec": "open", + "_where": "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules", + "author": { + "name": "J Jordan", + "email": "jjrdn@styosis.com" + }, + "bugs": { + "url": "https://github.com/pwnall/node-open/issues" + }, + "contributors": [ + { + "name": "Victor Costan", + "email": "victor@costan.us", + "url": "http://www.costan.us" + } + ], + "dependencies": {}, + "description": "open a file or url in the user's preferred application", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc", + "tarball": "https://registry.npmjs.org/open/-/open-0.0.5.tgz" + }, + "engines": { + "node": ">= 0.6.0" + }, + "homepage": "https://github.com/jjrdn/node-open", + "keywords": [ + "start", + "open", + "browser", + "editor", + "default" + ], + "license": "MIT", + "main": "lib/open.js", + "maintainers": [ + { + "name": "jjrdn", + "email": "jjrdn@styosis.com" + }, + { + "name": "pwnall", + "email": "costan@gmail.com" + } + ], + "name": "open", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/pwnall/node-open.git" + }, + "scripts": { + "test": "node_modules/mocha/bin/mocha" + }, + "version": "0.0.5" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/open/vendor/xdg-open b/pype/premiere/extensions/com.pype.avalon/node_modules/open/vendor/xdg-open new file mode 100644 index 0000000000..13caac1a43 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/open/vendor/xdg-open @@ -0,0 +1,767 @@ +#!/bin/sh +#--------------------------------------------- +# xdg-open +# +# Utility script to open a URL in the registered default application. +# +# Refer to the usage() function below for usage. +# +# Copyright 2009-2010, Fathi Boudra +# Copyright 2009-2010, Rex Dieter +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# 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: +# +# 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. +# +#--------------------------------------------- + +manualpage() +{ +cat << _MANUALPAGE +Name + + xdg-open -- opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +Description + + xdg-open opens a file or URL in the user's preferred + application. If a URL is provided the URL will be opened in the + user's preferred web browser. If a file is provided the file + will be opened in the preferred application for files of that + type. xdg-open supports file, ftp, http and https URLs. + + xdg-open is for use inside a desktop session only. It is not + recommended to use xdg-open as root. + +Options + + --help + Show command synopsis. + + --manual + Show this manual page. + + --version + Show the xdg-utils version information. + +Exit Codes + + An exit code of 0 indicates success while a non-zero exit code + indicates failure. The following failure codes can be returned: + + 1 + Error in command line syntax. + + 2 + One of the files passed on the command line did not + exist. + + 3 + A required tool could not be found. + + 4 + The action failed. + +Examples + +xdg-open 'http://www.freedesktop.org/' + + Opens the freedesktop.org website in the user's default + browser. + +xdg-open /tmp/foobar.png + + Opens the PNG image file /tmp/foobar.png in the user's default + image viewing application. +_MANUALPAGE +} + +usage() +{ +cat << _USAGE + xdg-open -- opens a file or URL in the user's preferred + application + +Synopsis + + xdg-open { file | URL } + + xdg-open { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +#------------------------------------------------------------- +# map a binary to a .desktop file +binary_to_desktop_file() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + binary="`which "$1"`" + binary="`readlink -f "$binary"`" + base="`basename "$binary"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] || continue + [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue + for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do + [ -r "$file" ] || continue + # Check to make sure it's worth the processing. + grep -q "^Exec.*$base" "$file" || continue + # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). + grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + if [ x"`readlink -f "$command"`" = x"$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return + fi + done + done +} + +#------------------------------------------------------------- +# map a .desktop file to a binary +## FIXME: handle vendor dir case +desktop_file_to_binary() +{ + search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + desktop="`basename "$1"`" + IFS=: + for dir in $search; do + unset IFS + [ "$dir" ] && [ -d "$dir/applications" ] || continue + file="$dir/applications/$desktop" + [ -r "$file" ] || continue + # Remove any arguments (%F, %f, %U, %u, etc.). + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command="`which "$command"`" + readlink -f "$command" + return + done +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + echo "Try 'xdg-open --help' for more information." >&2 + else + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to write a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [a-zA-Z]*-*) + return + ;; + esac + + echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" ] || [ ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-open 1.1.0 rc1" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + # see https://bugs.freedesktop.org/show_bug.cgi?id=34164 + unset GREP_OPTIONS + + if [ -n "${XDG_CURRENT_DESKTOP}" ]; then + case "${XDG_CURRENT_DESKTOP}" in + GNOME) + DE=gnome; + ;; + KDE) + DE=kde; + ;; + LXDE) + DE=lxde; + ;; + XFCE) + DE=xfce + esac + fi + + if [ x"$DE" = x"" ]; then + # classic fallbacks + if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif [ x"$MATE_DESKTOP_SESSION_ID" != x"" ]; then DE=mate; + elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; + elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce + fi + fi + + if [ x"$DE" = x"" ]; then + # fallback to checking $DESKTOP_SESSION + case "$DESKTOP_SESSION" in + gnome) + DE=gnome; + ;; + LXDE|Lubuntu) + DE=lxde; + ;; + xfce|xfce4|'Xfce Session') + DE=xfce; + ;; + esac + fi + + if [ x"$DE" = x"" ]; then + # fallback to uname output for other platforms + case "$(uname 2>/dev/null)" in + Darwin) + DE=darwin; + ;; + esac + fi + + if [ x"$DE" = x"gnome" ]; then + # gnome-default-applications-properties is only available in GNOME 2.x + # but not in GNOME 3.x + which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` + major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +# This handles backslashes but not quote marks. +first_word() +{ + read first rest + echo "$first" +} + +last_word() +{ + read first rest + echo "$rest" +} + +open_darwin() +{ + open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_kde() +{ + if kde-open -v 2>/dev/null 1>&2; then + kde-open "$1" + else + if [ x"$KDE_SESSION_VERSION" = x"4" ]; then + kfmclient openURL "$1" + else + kfmclient exec "$1" + kfmclient_fix_exit_code $? + fi + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome() +{ + if gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + gnome-open "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_mate() +{ + if gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + mate-open "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_xfce() +{ + exo-open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +#----------------------------------------- +# Recursively search .desktop file + +search_desktop_file() +{ + local default="$1" + local dir="$2" + local arg="$3" + + local file="" + # look for both vendor-app.desktop, vendor/app.desktop + if [ -r "$dir/$default" ]; then + file="$dir/$default" + elif [ -r "$dir/`echo $default | sed -e 's|-|/|'`" ]; then + file="$dir/`echo $default | sed -e 's|-|/|'`" + fi + + if [ -r "$file" ] ; then + command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" + command_exec=`which $command 2>/dev/null` + arguments="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | last_word`" + arg_one="`echo $arg | sed 's/&/\\\\&/g'`" + arguments_exec="`echo $arguments | sed -e 's*%[fFuU]*"'"$arg_one"'"*g'`" + + if [ -x "$command_exec" ] ; then + if echo $arguments | grep -iq '%[fFuU]' ; then + echo START $command_exec $arguments_exec + eval $command_exec $arguments_exec + else + echo START $command_exec $arguments_exec "$arg" + eval $command_exec $arguments_exec "$arg" + fi + + if [ $? -eq 0 ]; then + exit_success + fi + fi + fi + + for d in $dir/*/; do + [ -d "$d" ] && search_desktop_file "$default" "$d" "$arg" + done +} + + +open_generic_xdg_mime() +{ + filetype="$2" + default=`xdg-mime query default "$filetype"` + if [ -n "$default" ] ; then + xdg_user_dir="$XDG_DATA_HOME" + [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" + + xdg_system_dirs="$XDG_DATA_DIRS" + [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ + +DEBUG 3 "$xdg_user_dir:$xdg_system_dirs" + for x in `echo "$xdg_user_dir:$xdg_system_dirs" | sed 's/:/ /g'`; do + search_desktop_file "$default" "$x/applications/" "$1" + done + fi +} + +open_generic_xdg_file_mime() +{ + filetype=`xdg-mime query filetype "$1" | sed "s/;.*//"` + open_generic_xdg_mime "$1" "$filetype" +} + +open_generic_xdg_x_scheme_handler() +{ + scheme="`echo $1 | sed -n 's/\(^[[:alnum:]+\.-]*\):.*$/\1/p'`" + if [ -n $scheme ]; then + filetype="x-scheme-handler/$scheme" + open_generic_xdg_mime "$1" "$filetype" + fi +} + +open_generic() +{ + # Paths or file:// URLs + if (echo "$1" | grep -q '^file://' || + ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:'); then + + local file="$1" + + # Decode URLs + if echo "$file" | grep -q '^file:///'; then + file=${file#file://} + file="$(printf "$(echo "$file" | sed -e 's@%\([a-f0-9A-F]\{2\}\)@\\x\1@g')")" + fi + check_input_file "$file" + + open_generic_xdg_file_mime "$file" + + if [ -f /etc/debian_version ] && + which run-mailcap 2>/dev/null 1>&2; then + run-mailcap --action=view "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + + if mimeopen -v 2>/dev/null 1>&2; then + mimeopen -L -n "$file" + if [ $? -eq 0 ]; then + exit_success + fi + fi + fi + + open_generic_xdg_x_scheme_handler "$1" + + IFS=":" + for browser in $BROWSER; do + if [ x"$browser" != x"" ]; then + + browser_with_arg=`printf "$browser" "$1" 2>/dev/null` + if [ $? -ne 0 ]; then + browser_with_arg=$browser; + fi + + if [ x"$browser_with_arg" = x"$browser" ]; then + eval '$browser $1'$xdg_redirect_output; + else eval '$browser_with_arg'$xdg_redirect_output; + fi + + if [ $? -eq 0 ]; then + exit_success; + fi + fi + done + + exit_failure_operation_impossible "no method available for opening '$1'" +} + +open_lxde() +{ + # pcmanfm only knows how to handle file:// urls and filepaths, it seems. + if (echo "$1" | grep -q '^file://' || + ! echo "$1" | egrep -q '^[[:alpha:]+\.\-]+:') + then + local file="$(echo "$1" | sed 's%^file://%%')" + + # handle relative paths + if ! echo "$file" | grep -q '^/'; then + file="$(pwd)/$file" + fi + + pcmanfm "$file" + + else + open_generic "$1" + fi + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +[ x"$1" != x"" ] || exit_failure_syntax + +url= +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + *) + if [ -n "$url" ] ; then + exit_failure_syntax "unexpected argument '$parm'" + fi + url="$parm" + ;; + esac +done + +if [ -z "${url}" ] ; then + exit_failure_syntax "file or URL argument missing" +fi + +detectDE + +if [ x"$DE" = x"" ]; then + DE=generic +fi + +DEBUG 2 "Selected DE $DE" + +# if BROWSER variable is not set, check some well known browsers instead +if [ x"$BROWSER" = x"" ]; then + BROWSER=links2:elinks:links:lynx:w3m + if [ -n "$DISPLAY" ]; then + BROWSER=x-www-browser:firefox:seamonkey:mozilla:epiphany:konqueror:chromium-browser:google-chrome:$BROWSER + fi +fi + +case "$DE" in + kde) + open_kde "$url" + ;; + + gnome*) + open_gnome "$url" + ;; + + mate) + open_mate "$url" + ;; + + xfce) + open_xfce "$url" + ;; + + lxde) + open_lxde "$url" + ;; + + generic) + open_generic "$url" + ;; + + *) + exit_failure_operation_impossible "no method available for opening '$url'" + ;; +esac diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/CHANGELOG.md b/pype/premiere/extensions/com.pype.avalon/node_modules/request/CHANGELOG.md new file mode 100644 index 0000000000..af76719b4b --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/CHANGELOG.md @@ -0,0 +1,674 @@ +## Change Log + +### v2.81.0 (2017/03/09) +- [#2584](https://github.com/request/request/pull/2584) Security issue: Upgrade qs to version 6.4.0 (@sergejmueller) +- [#2574](https://github.com/request/request/pull/2574) Migrating to safe-buffer for improved security. (@mikeal) +- [#2573](https://github.com/request/request/pull/2573) fixes #2572 (@ahmadnassri) + +### v2.80.0 (2017/03/04) +- [#2571](https://github.com/request/request/pull/2571) Correctly format the Host header for IPv6 addresses (@JamesMGreene) +- [#2558](https://github.com/request/request/pull/2558) Update README.md example snippet (@FredKSchott) +- [#2221](https://github.com/request/request/pull/2221) Adding a simple Response object reference in argument specification (@calamarico) +- [#2452](https://github.com/request/request/pull/2452) Adds .timings array with DNC, TCP, request and response times (@nicjansma) +- [#2553](https://github.com/request/request/pull/2553) add ISSUE_TEMPLATE, move PR template (@FredKSchott) +- [#2539](https://github.com/request/request/pull/2539) Create PULL_REQUEST_TEMPLATE.md (@FredKSchott) +- [#2524](https://github.com/request/request/pull/2524) Update caseless to version 0.12.0 🚀 (@greenkeeperio-bot) +- [#2460](https://github.com/request/request/pull/2460) Fix wrong MIME type in example (@OwnageIsMagic) +- [#2514](https://github.com/request/request/pull/2514) Change tags to keywords in package.json (@humphd) +- [#2492](https://github.com/request/request/pull/2492) More lenient gzip decompression (@addaleax) + +### v2.79.0 (2016/11/18) +- [#2368](https://github.com/request/request/pull/2368) Fix typeof check in test-pool.js (@forivall) +- [#2394](https://github.com/request/request/pull/2394) Use `files` in package.json (@SimenB) +- [#2463](https://github.com/request/request/pull/2463) AWS support for session tokens for temporary credentials (@simov) +- [#2467](https://github.com/request/request/pull/2467) Migrate to uuid (@simov, @antialias) +- [#2459](https://github.com/request/request/pull/2459) Update taper to version 0.5.0 🚀 (@greenkeeperio-bot) +- [#2448](https://github.com/request/request/pull/2448) Make other connect timeout test more reliable too (@mscdex) + +### v2.78.0 (2016/11/03) +- [#2447](https://github.com/request/request/pull/2447) Always set request timeout on keep-alive connections (@mscdex) + +### v2.77.0 (2016/11/03) +- [#2439](https://github.com/request/request/pull/2439) Fix socket 'connect' listener handling (@mscdex) +- [#2442](https://github.com/request/request/pull/2442) 👻😱 Node.js 0.10 is unmaintained 😱👻 (@greenkeeperio-bot) +- [#2435](https://github.com/request/request/pull/2435) Add followOriginalHttpMethod to redirect to original HTTP method (@kirrg001) +- [#2414](https://github.com/request/request/pull/2414) Improve test-timeout reliability (@mscdex) + +### v2.76.0 (2016/10/25) +- [#2424](https://github.com/request/request/pull/2424) Handle buffers directly instead of using "bl" (@zertosh) +- [#2415](https://github.com/request/request/pull/2415) Re-enable timeout tests on Travis + other fixes (@mscdex) +- [#2431](https://github.com/request/request/pull/2431) Improve timeouts accuracy and node v6.8.0+ compatibility (@mscdex, @greenkeeperio-bot) +- [#2428](https://github.com/request/request/pull/2428) Update qs to version 6.3.0 🚀 (@greenkeeperio-bot) +- [#2420](https://github.com/request/request/pull/2420) change .on to .once, remove possible memory leaks (@duereg) +- [#2426](https://github.com/request/request/pull/2426) Remove "isFunction" helper in favor of "typeof" check (@zertosh) +- [#2425](https://github.com/request/request/pull/2425) Simplify "defer" helper creation (@zertosh) +- [#2402](https://github.com/request/request/pull/2402) form-data@2.1.1 breaks build 🚨 (@greenkeeperio-bot) +- [#2393](https://github.com/request/request/pull/2393) Update form-data to version 2.1.0 🚀 (@greenkeeperio-bot) + +### v2.75.0 (2016/09/17) +- [#2381](https://github.com/request/request/pull/2381) Drop support for Node 0.10 (@simov) +- [#2377](https://github.com/request/request/pull/2377) Update form-data to version 2.0.0 🚀 (@greenkeeperio-bot) +- [#2353](https://github.com/request/request/pull/2353) Add greenkeeper ignored packages (@simov) +- [#2351](https://github.com/request/request/pull/2351) Update karma-tap to version 3.0.1 🚀 (@greenkeeperio-bot) +- [#2348](https://github.com/request/request/pull/2348) form-data@1.0.1 breaks build 🚨 (@greenkeeperio-bot) +- [#2349](https://github.com/request/request/pull/2349) Check error type instead of string (@scotttrinh) + +### v2.74.0 (2016/07/22) +- [#2295](https://github.com/request/request/pull/2295) Update tough-cookie to 2.3.0 (@stash-sfdc) +- [#2280](https://github.com/request/request/pull/2280) Update karma-tap to version 2.0.1 🚀 (@greenkeeperio-bot) + +### v2.73.0 (2016/07/09) +- [#2240](https://github.com/request/request/pull/2240) Remove connectionErrorHandler to fix #1903 (@zarenner) +- [#2251](https://github.com/request/request/pull/2251) tape@4.6.0 breaks build 🚨 (@greenkeeperio-bot) +- [#2225](https://github.com/request/request/pull/2225) Update docs (@ArtskydJ) +- [#2203](https://github.com/request/request/pull/2203) Update browserify to version 13.0.1 🚀 (@greenkeeperio-bot) +- [#2275](https://github.com/request/request/pull/2275) Update karma to version 1.1.1 🚀 (@greenkeeperio-bot) +- [#2204](https://github.com/request/request/pull/2204) Add codecov.yml and disable PR comments (@simov) +- [#2212](https://github.com/request/request/pull/2212) Fix link to http.IncomingMessage documentation (@nazieb) +- [#2208](https://github.com/request/request/pull/2208) Update to form-data RC4 and pass null values to it (@simov) +- [#2207](https://github.com/request/request/pull/2207) Move aws4 require statement to the top (@simov) +- [#2199](https://github.com/request/request/pull/2199) Update karma-coverage to version 1.0.0 🚀 (@greenkeeperio-bot) +- [#2206](https://github.com/request/request/pull/2206) Update qs to version 6.2.0 🚀 (@greenkeeperio-bot) +- [#2205](https://github.com/request/request/pull/2205) Use server-destory to close hanging sockets in tests (@simov) +- [#2200](https://github.com/request/request/pull/2200) Update karma-cli to version 1.0.0 🚀 (@greenkeeperio-bot) + +### v2.72.0 (2016/04/17) +- [#2176](https://github.com/request/request/pull/2176) Do not try to pipe Gzip responses with no body (@simov) +- [#2175](https://github.com/request/request/pull/2175) Add 'delete' alias for the 'del' API method (@simov, @MuhanZou) +- [#2172](https://github.com/request/request/pull/2172) Add support for deflate content encoding (@czardoz) +- [#2169](https://github.com/request/request/pull/2169) Add callback option (@simov) +- [#2165](https://github.com/request/request/pull/2165) Check for self.req existence inside the write method (@simov) +- [#2167](https://github.com/request/request/pull/2167) Fix TravisCI badge reference master branch (@a0viedo) + +### v2.71.0 (2016/04/12) +- [#2164](https://github.com/request/request/pull/2164) Catch errors from the underlying http module (@simov) + +### v2.70.0 (2016/04/05) +- [#2147](https://github.com/request/request/pull/2147) Update eslint to version 2.5.3 🚀 (@simov, @greenkeeperio-bot) +- [#2009](https://github.com/request/request/pull/2009) Support JSON stringify replacer argument. (@elyobo) +- [#2142](https://github.com/request/request/pull/2142) Update eslint to version 2.5.1 🚀 (@greenkeeperio-bot) +- [#2128](https://github.com/request/request/pull/2128) Update browserify-istanbul to version 2.0.0 🚀 (@greenkeeperio-bot) +- [#2115](https://github.com/request/request/pull/2115) Update eslint to version 2.3.0 🚀 (@simov, @greenkeeperio-bot) +- [#2089](https://github.com/request/request/pull/2089) Fix badges (@simov) +- [#2092](https://github.com/request/request/pull/2092) Update browserify-istanbul to version 1.0.0 🚀 (@greenkeeperio-bot) +- [#2079](https://github.com/request/request/pull/2079) Accept read stream as body option (@simov) +- [#2070](https://github.com/request/request/pull/2070) Update bl to version 1.1.2 🚀 (@greenkeeperio-bot) +- [#2063](https://github.com/request/request/pull/2063) Up bluebird and oauth-sign (@simov) +- [#2058](https://github.com/request/request/pull/2058) Karma fixes for latest versions (@eiriksm) +- [#2057](https://github.com/request/request/pull/2057) Update contributing guidelines (@simov) +- [#2054](https://github.com/request/request/pull/2054) Update qs to version 6.1.0 🚀 (@greenkeeperio-bot) + +### v2.69.0 (2016/01/27) +- [#2041](https://github.com/request/request/pull/2041) restore aws4 as regular dependency (@rmg) + +### v2.68.0 (2016/01/27) +- [#2036](https://github.com/request/request/pull/2036) Add AWS Signature Version 4 (@simov, @mirkods) +- [#2022](https://github.com/request/request/pull/2022) Convert numeric multipart bodies to string (@simov, @feross) +- [#2024](https://github.com/request/request/pull/2024) Update har-validator dependency for nsp advisory #76 (@TylerDixon) +- [#2016](https://github.com/request/request/pull/2016) Update qs to version 6.0.2 🚀 (@greenkeeperio-bot) +- [#2007](https://github.com/request/request/pull/2007) Use the `extend` module instead of util._extend (@simov) +- [#2003](https://github.com/request/request/pull/2003) Update browserify to version 13.0.0 🚀 (@greenkeeperio-bot) +- [#1989](https://github.com/request/request/pull/1989) Update buffer-equal to version 1.0.0 🚀 (@greenkeeperio-bot) +- [#1956](https://github.com/request/request/pull/1956) Check form-data content-length value before setting up the header (@jongyoonlee) +- [#1958](https://github.com/request/request/pull/1958) Use IncomingMessage.destroy method (@simov) +- [#1952](https://github.com/request/request/pull/1952) Adds example for Tor proxy (@prometheansacrifice) +- [#1943](https://github.com/request/request/pull/1943) Update eslint to version 1.10.3 🚀 (@simov, @greenkeeperio-bot) +- [#1924](https://github.com/request/request/pull/1924) Update eslint to version 1.10.1 🚀 (@greenkeeperio-bot) +- [#1915](https://github.com/request/request/pull/1915) Remove content-length and transfer-encoding headers from defaultProxyHeaderWhiteList (@yaxia) + +### v2.67.0 (2015/11/19) +- [#1913](https://github.com/request/request/pull/1913) Update http-signature to version 1.1.0 🚀 (@greenkeeperio-bot) + +### v2.66.0 (2015/11/18) +- [#1906](https://github.com/request/request/pull/1906) Update README URLs based on HTTP redirects (@ReadmeCritic) +- [#1905](https://github.com/request/request/pull/1905) Convert typed arrays into regular buffers (@simov) +- [#1902](https://github.com/request/request/pull/1902) node-uuid@1.4.7 breaks build 🚨 (@greenkeeperio-bot) +- [#1894](https://github.com/request/request/pull/1894) Fix tunneling after redirection from https (Original: #1881) (@simov, @falms) +- [#1893](https://github.com/request/request/pull/1893) Update eslint to version 1.9.0 🚀 (@greenkeeperio-bot) +- [#1852](https://github.com/request/request/pull/1852) Update eslint to version 1.7.3 🚀 (@simov, @greenkeeperio-bot, @paulomcnally, @michelsalib, @arbaaz, @nsklkn, @LoicMahieu, @JoshWillik, @jzaefferer, @ryanwholey, @djchie, @thisconnect, @mgenereu, @acroca, @Sebmaster, @KoltesDigital) +- [#1876](https://github.com/request/request/pull/1876) Implement loose matching for har mime types (@simov) +- [#1875](https://github.com/request/request/pull/1875) Update bluebird to version 3.0.2 🚀 (@simov, @greenkeeperio-bot) +- [#1871](https://github.com/request/request/pull/1871) Update browserify to version 12.0.1 🚀 (@greenkeeperio-bot) +- [#1866](https://github.com/request/request/pull/1866) Add missing quotes on x-token property in README (@miguelmota) +- [#1874](https://github.com/request/request/pull/1874) Fix typo in README.md (@gswalden) +- [#1860](https://github.com/request/request/pull/1860) Improve referer header tests and docs (@simov) +- [#1861](https://github.com/request/request/pull/1861) Remove redundant call to Stream constructor (@watson) +- [#1857](https://github.com/request/request/pull/1857) Fix Referer header to point to the original host name (@simov) +- [#1850](https://github.com/request/request/pull/1850) Update karma-coverage to version 0.5.3 🚀 (@greenkeeperio-bot) +- [#1847](https://github.com/request/request/pull/1847) Use node's latest version when building (@simov) +- [#1836](https://github.com/request/request/pull/1836) Tunnel: fix wrong property name (@KoltesDigital) +- [#1820](https://github.com/request/request/pull/1820) Set href as request.js uses it (@mgenereu) +- [#1840](https://github.com/request/request/pull/1840) Update http-signature to version 1.0.2 🚀 (@greenkeeperio-bot) +- [#1845](https://github.com/request/request/pull/1845) Update istanbul to version 0.4.0 🚀 (@greenkeeperio-bot) + +### v2.65.0 (2015/10/11) +- [#1833](https://github.com/request/request/pull/1833) Update aws-sign2 to version 0.6.0 🚀 (@greenkeeperio-bot) +- [#1811](https://github.com/request/request/pull/1811) Enable loose cookie parsing in tough-cookie (@Sebmaster) +- [#1830](https://github.com/request/request/pull/1830) Bring back tilde ranges for all dependencies (@simov) +- [#1821](https://github.com/request/request/pull/1821) Implement support for RFC 2617 MD5-sess algorithm. (@BigDSK) +- [#1828](https://github.com/request/request/pull/1828) Updated qs dependency to 5.2.0 (@acroca) +- [#1818](https://github.com/request/request/pull/1818) Extract `readResponseBody` method out of `onRequestResponse` (@pvoisin) +- [#1819](https://github.com/request/request/pull/1819) Run stringify once (@mgenereu) +- [#1814](https://github.com/request/request/pull/1814) Updated har-validator to version 2.0.2 (@greenkeeperio-bot) +- [#1807](https://github.com/request/request/pull/1807) Updated tough-cookie to version 2.1.0 (@greenkeeperio-bot) +- [#1800](https://github.com/request/request/pull/1800) Add caret ranges for devDependencies, except eslint (@simov) +- [#1799](https://github.com/request/request/pull/1799) Updated karma-browserify to version 4.4.0 (@greenkeeperio-bot) +- [#1797](https://github.com/request/request/pull/1797) Updated tape to version 4.2.0 (@greenkeeperio-bot) +- [#1788](https://github.com/request/request/pull/1788) Pinned all dependencies (@greenkeeperio-bot) + +### v2.64.0 (2015/09/25) +- [#1787](https://github.com/request/request/pull/1787) npm ignore examples, release.sh and disabled.appveyor.yml (@thisconnect) +- [#1775](https://github.com/request/request/pull/1775) Fix typo in README.md (@djchie) +- [#1776](https://github.com/request/request/pull/1776) Changed word 'conjuction' to read 'conjunction' in README.md (@ryanwholey) +- [#1785](https://github.com/request/request/pull/1785) Revert: Set default application/json content-type when using json option #1772 (@simov) + +### v2.63.0 (2015/09/21) +- [#1772](https://github.com/request/request/pull/1772) Set default application/json content-type when using json option (@jzaefferer) + +### v2.62.0 (2015/09/15) +- [#1768](https://github.com/request/request/pull/1768) Add node 4.0 to the list of build targets (@simov) +- [#1767](https://github.com/request/request/pull/1767) Query strings now cooperate with unix sockets (@JoshWillik) +- [#1750](https://github.com/request/request/pull/1750) Revert doc about installation of tough-cookie added in #884 (@LoicMahieu) +- [#1746](https://github.com/request/request/pull/1746) Missed comma in Readme (@nsklkn) +- [#1743](https://github.com/request/request/pull/1743) Fix options not being initialized in defaults method (@simov) + +### v2.61.0 (2015/08/19) +- [#1721](https://github.com/request/request/pull/1721) Minor fix in README.md (@arbaaz) +- [#1733](https://github.com/request/request/pull/1733) Avoid useless Buffer transformation (@michelsalib) +- [#1726](https://github.com/request/request/pull/1726) Update README.md (@paulomcnally) +- [#1715](https://github.com/request/request/pull/1715) Fix forever option in node > 0.10 #1709 (@calibr) +- [#1716](https://github.com/request/request/pull/1716) Do not create Buffer from Object in setContentLength(iojs v3.0 issue) (@calibr) +- [#1711](https://github.com/request/request/pull/1711) Add ability to detect connect timeouts (@kevinburke) +- [#1712](https://github.com/request/request/pull/1712) Set certificate expiration to August 2, 2018 (@kevinburke) +- [#1700](https://github.com/request/request/pull/1700) debug() when JSON.parse() on a response body fails (@phillipj) + +### v2.60.0 (2015/07/21) +- [#1687](https://github.com/request/request/pull/1687) Fix caseless bug - content-type not being set for multipart/form-data (@simov, @garymathews) + +### v2.59.0 (2015/07/20) +- [#1671](https://github.com/request/request/pull/1671) Add tests and docs for using the agent, agentClass, agentOptions and forever options. Forever option defaults to using http(s).Agent in node 0.12+ (@simov) +- [#1679](https://github.com/request/request/pull/1679) Fix - do not remove OAuth param when using OAuth realm (@simov, @jhalickman) +- [#1668](https://github.com/request/request/pull/1668) updated dependencies (@deamme) +- [#1656](https://github.com/request/request/pull/1656) Fix form method (@simov) +- [#1651](https://github.com/request/request/pull/1651) Preserve HEAD method when using followAllRedirects (@simov) +- [#1652](https://github.com/request/request/pull/1652) Update `encoding` option documentation in README.md (@daniel347x) +- [#1650](https://github.com/request/request/pull/1650) Allow content-type overriding when using the `form` option (@simov) +- [#1646](https://github.com/request/request/pull/1646) Clarify the nature of setting `ca` in `agentOptions` (@jeffcharles) + +### v2.58.0 (2015/06/16) +- [#1638](https://github.com/request/request/pull/1638) Use the `extend` module to deep extend in the defaults method (@simov) +- [#1631](https://github.com/request/request/pull/1631) Move tunnel logic into separate module (@simov) +- [#1634](https://github.com/request/request/pull/1634) Fix OAuth query transport_method (@simov) +- [#1603](https://github.com/request/request/pull/1603) Add codecov (@simov) + +### v2.57.0 (2015/05/31) +- [#1615](https://github.com/request/request/pull/1615) Replace '.client' with '.socket' as the former was deprecated in 2.2.0. (@ChALkeR) + +### v2.56.0 (2015/05/28) +- [#1610](https://github.com/request/request/pull/1610) Bump module dependencies (@simov) +- [#1600](https://github.com/request/request/pull/1600) Extract the querystring logic into separate module (@simov) +- [#1607](https://github.com/request/request/pull/1607) Re-generate certificates (@simov) +- [#1599](https://github.com/request/request/pull/1599) Move getProxyFromURI logic below the check for Invaild URI (#1595) (@simov) +- [#1598](https://github.com/request/request/pull/1598) Fix the way http verbs are defined in order to please intellisense IDEs (@simov, @flannelJesus) +- [#1591](https://github.com/request/request/pull/1591) A few minor fixes: (@simov) +- [#1584](https://github.com/request/request/pull/1584) Refactor test-default tests (according to comments in #1430) (@simov) +- [#1585](https://github.com/request/request/pull/1585) Fixing documentation regarding TLS options (#1583) (@mainakae) +- [#1574](https://github.com/request/request/pull/1574) Refresh the oauth_nonce on redirect (#1573) (@simov) +- [#1570](https://github.com/request/request/pull/1570) Discovered tests that weren't properly running (@seanstrom) +- [#1569](https://github.com/request/request/pull/1569) Fix pause before response arrives (@kevinoid) +- [#1558](https://github.com/request/request/pull/1558) Emit error instead of throw (@simov) +- [#1568](https://github.com/request/request/pull/1568) Fix stall when piping gzipped response (@kevinoid) +- [#1560](https://github.com/request/request/pull/1560) Update combined-stream (@apechimp) +- [#1543](https://github.com/request/request/pull/1543) Initial support for oauth_body_hash on json payloads (@simov, @aesopwolf) +- [#1541](https://github.com/request/request/pull/1541) Fix coveralls (@simov) +- [#1540](https://github.com/request/request/pull/1540) Fix recursive defaults for convenience methods (@simov) +- [#1536](https://github.com/request/request/pull/1536) More eslint style rules (@froatsnook) +- [#1533](https://github.com/request/request/pull/1533) Adding dependency status bar to README.md (@YasharF) +- [#1539](https://github.com/request/request/pull/1539) ensure the latest version of har-validator is included (@ahmadnassri) +- [#1516](https://github.com/request/request/pull/1516) forever+pool test (@devTristan) + +### v2.55.0 (2015/04/05) +- [#1520](https://github.com/request/request/pull/1520) Refactor defaults (@simov) +- [#1525](https://github.com/request/request/pull/1525) Delete request headers with undefined value. (@froatsnook) +- [#1521](https://github.com/request/request/pull/1521) Add promise tests (@simov) +- [#1518](https://github.com/request/request/pull/1518) Fix defaults (@simov) +- [#1515](https://github.com/request/request/pull/1515) Allow static invoking of convenience methods (@simov) +- [#1505](https://github.com/request/request/pull/1505) Fix multipart boundary extraction regexp (@simov) +- [#1510](https://github.com/request/request/pull/1510) Fix basic auth form data (@simov) + +### v2.54.0 (2015/03/24) +- [#1501](https://github.com/request/request/pull/1501) HTTP Archive 1.2 support (@ahmadnassri) +- [#1486](https://github.com/request/request/pull/1486) Add a test for the forever agent (@akshayp) +- [#1500](https://github.com/request/request/pull/1500) Adding handling for no auth method and null bearer (@philberg) +- [#1498](https://github.com/request/request/pull/1498) Add table of contents in readme (@simov) +- [#1477](https://github.com/request/request/pull/1477) Add support for qs options via qsOptions key (@simov) +- [#1496](https://github.com/request/request/pull/1496) Parameters encoded to base 64 should be decoded as UTF-8, not ASCII. (@albanm) +- [#1494](https://github.com/request/request/pull/1494) Update eslint (@froatsnook) +- [#1474](https://github.com/request/request/pull/1474) Require Colon in Basic Auth (@erykwalder) +- [#1481](https://github.com/request/request/pull/1481) Fix baseUrl and redirections. (@burningtree) +- [#1469](https://github.com/request/request/pull/1469) Feature/base url (@froatsnook) +- [#1459](https://github.com/request/request/pull/1459) Add option to time request/response cycle (including rollup of redirects) (@aaron-em) +- [#1468](https://github.com/request/request/pull/1468) Re-enable io.js/node 0.12 build (@simov, @mikeal, @BBB) +- [#1442](https://github.com/request/request/pull/1442) Fixed the issue with strictSSL tests on 0.12 & io.js by explicitly setting a cipher that matches the cert. (@BBB, @nickmccurdy, @demohi, @simov, @0x4139) +- [#1460](https://github.com/request/request/pull/1460) localAddress or proxy config is lost when redirecting (@simov, @0x4139) +- [#1453](https://github.com/request/request/pull/1453) Test on Node.js 0.12 and io.js with allowed failures (@nickmccurdy, @demohi) +- [#1426](https://github.com/request/request/pull/1426) Fixing tests to pass on io.js and node 0.12 (only test-https.js stiff failing) (@mikeal) +- [#1446](https://github.com/request/request/pull/1446) Missing HTTP referer header with redirects Fixes #1038 (@simov, @guimon) +- [#1428](https://github.com/request/request/pull/1428) Deprecate Node v0.8.x (@nylen) +- [#1436](https://github.com/request/request/pull/1436) Add ability to set a requester without setting default options (@tikotzky) +- [#1435](https://github.com/request/request/pull/1435) dry up verb methods (@sethpollack) +- [#1423](https://github.com/request/request/pull/1423) Allow fully qualified multipart content-type header (@simov) +- [#1430](https://github.com/request/request/pull/1430) Fix recursive requester (@tikotzky) +- [#1429](https://github.com/request/request/pull/1429) Throw error when making HEAD request with a body (@tikotzky) +- [#1419](https://github.com/request/request/pull/1419) Add note that the project is broken in 0.12.x (@nylen) +- [#1413](https://github.com/request/request/pull/1413) Fix basic auth (@simov) +- [#1397](https://github.com/request/request/pull/1397) Improve pipe-from-file tests (@nylen) + +### v2.53.0 (2015/02/02) +- [#1396](https://github.com/request/request/pull/1396) Do not rfc3986 escape JSON bodies (@nylen, @simov) +- [#1392](https://github.com/request/request/pull/1392) Improve `timeout` option description (@watson) + +### v2.52.0 (2015/02/02) +- [#1383](https://github.com/request/request/pull/1383) Add missing HTTPS options that were not being passed to tunnel (@brichard19) (@nylen) +- [#1388](https://github.com/request/request/pull/1388) Upgrade mime-types package version (@roderickhsiao) +- [#1389](https://github.com/request/request/pull/1389) Revise Setup Tunnel Function (@seanstrom) +- [#1374](https://github.com/request/request/pull/1374) Allow explicitly disabling tunneling for proxied https destinations (@nylen) +- [#1376](https://github.com/request/request/pull/1376) Use karma-browserify for tests. Add browser test coverage reporter. (@eiriksm) +- [#1366](https://github.com/request/request/pull/1366) Refactor OAuth into separate module (@simov) +- [#1373](https://github.com/request/request/pull/1373) Rewrite tunnel test to be pure Node.js (@nylen) +- [#1371](https://github.com/request/request/pull/1371) Upgrade test reporter (@nylen) +- [#1360](https://github.com/request/request/pull/1360) Refactor basic, bearer, digest auth logic into separate class (@simov) +- [#1354](https://github.com/request/request/pull/1354) Remove circular dependency from debugging code (@nylen) +- [#1351](https://github.com/request/request/pull/1351) Move digest auth into private prototype method (@simov) +- [#1352](https://github.com/request/request/pull/1352) Update hawk dependency to ~2.3.0 (@mridgway) +- [#1353](https://github.com/request/request/pull/1353) Correct travis-ci badge (@dogancelik) +- [#1349](https://github.com/request/request/pull/1349) Make sure we return on errored browser requests. (@eiriksm) +- [#1346](https://github.com/request/request/pull/1346) getProxyFromURI Extraction Refactor (@seanstrom) +- [#1337](https://github.com/request/request/pull/1337) Standardize test ports on 6767 (@nylen) +- [#1341](https://github.com/request/request/pull/1341) Emit FormData error events as Request error events (@nylen, @rwky) +- [#1343](https://github.com/request/request/pull/1343) Clean up readme badges, and add Travis and Coveralls badges (@nylen) +- [#1345](https://github.com/request/request/pull/1345) Update README.md (@Aaron-Hartwig) +- [#1338](https://github.com/request/request/pull/1338) Always wait for server.close() callback in tests (@nylen) +- [#1342](https://github.com/request/request/pull/1342) Add mock https server and redo start of browser tests for this purpose. (@eiriksm) +- [#1339](https://github.com/request/request/pull/1339) Improve auth docs (@nylen) +- [#1335](https://github.com/request/request/pull/1335) Add support for OAuth plaintext signature method (@simov) +- [#1332](https://github.com/request/request/pull/1332) Add clean script to remove test-browser.js after the tests run (@seanstrom) +- [#1327](https://github.com/request/request/pull/1327) Fix errors generating coverage reports. (@nylen) +- [#1330](https://github.com/request/request/pull/1330) Return empty buffer upon empty response body and encoding is set to null (@seanstrom) +- [#1326](https://github.com/request/request/pull/1326) Use faster container-based infrastructure on Travis (@nylen) +- [#1315](https://github.com/request/request/pull/1315) Implement rfc3986 option (@simov, @nylen, @apoco, @DullReferenceException, @mmalecki, @oliamb, @cliffcrosland, @LewisJEllis, @eiriksm, @poislagarde) +- [#1314](https://github.com/request/request/pull/1314) Detect urlencoded form data header via regex (@simov) +- [#1317](https://github.com/request/request/pull/1317) Improve OAuth1.0 server side flow example (@simov) + +### v2.51.0 (2014/12/10) +- [#1310](https://github.com/request/request/pull/1310) Revert changes introduced in https://github.com/request/request/pull/1282 (@simov) + +### v2.50.0 (2014/12/09) +- [#1308](https://github.com/request/request/pull/1308) Add browser test to keep track of browserify compability. (@eiriksm) +- [#1299](https://github.com/request/request/pull/1299) Add optional support for jsonReviver (@poislagarde) +- [#1277](https://github.com/request/request/pull/1277) Add Coveralls configuration (@simov) +- [#1307](https://github.com/request/request/pull/1307) Upgrade form-data, add back browserify compability. Fixes #455. (@eiriksm) +- [#1305](https://github.com/request/request/pull/1305) Fix typo in README.md (@LewisJEllis) +- [#1288](https://github.com/request/request/pull/1288) Update README.md to explain custom file use case (@cliffcrosland) + +### v2.49.0 (2014/11/28) +- [#1295](https://github.com/request/request/pull/1295) fix(proxy): no-proxy false positive (@oliamb) +- [#1292](https://github.com/request/request/pull/1292) Upgrade `caseless` to 0.8.1 (@mmalecki) +- [#1276](https://github.com/request/request/pull/1276) Set transfer encoding for multipart/related to chunked by default (@simov) +- [#1275](https://github.com/request/request/pull/1275) Fix multipart content-type headers detection (@simov) +- [#1269](https://github.com/request/request/pull/1269) adds streams example for review (@tbuchok) +- [#1238](https://github.com/request/request/pull/1238) Add examples README.md (@simov) + +### v2.48.0 (2014/11/12) +- [#1263](https://github.com/request/request/pull/1263) Fixed a syntax error / typo in README.md (@xna2) +- [#1253](https://github.com/request/request/pull/1253) Add multipart chunked flag (@simov, @nylen) +- [#1251](https://github.com/request/request/pull/1251) Clarify that defaults() does not modify global defaults (@nylen) +- [#1250](https://github.com/request/request/pull/1250) Improve documentation for pool and maxSockets options (@nylen) +- [#1237](https://github.com/request/request/pull/1237) Documenting error handling when using streams (@vmattos) +- [#1244](https://github.com/request/request/pull/1244) Finalize changelog command (@nylen) +- [#1241](https://github.com/request/request/pull/1241) Fix typo (@alexanderGugel) +- [#1223](https://github.com/request/request/pull/1223) Show latest version number instead of "upcoming" in changelog (@nylen) +- [#1236](https://github.com/request/request/pull/1236) Document how to use custom CA in README (#1229) (@hypesystem) +- [#1228](https://github.com/request/request/pull/1228) Support for oauth with RSA-SHA1 signing (@nylen) +- [#1216](https://github.com/request/request/pull/1216) Made json and multipart options coexist (@nylen, @simov) +- [#1225](https://github.com/request/request/pull/1225) Allow header white/exclusive lists in any case. (@RReverser) + +### v2.47.0 (2014/10/26) +- [#1222](https://github.com/request/request/pull/1222) Move from mikeal/request to request/request (@nylen) +- [#1220](https://github.com/request/request/pull/1220) update qs dependency to 2.3.1 (@FredKSchott) +- [#1212](https://github.com/request/request/pull/1212) Improve tests/test-timeout.js (@nylen) +- [#1219](https://github.com/request/request/pull/1219) remove old globalAgent workaround for node 0.4 (@request) +- [#1214](https://github.com/request/request/pull/1214) Remove cruft left over from optional dependencies (@nylen) +- [#1215](https://github.com/request/request/pull/1215) Add proxyHeaderExclusiveList option for proxy-only headers. (@RReverser) +- [#1211](https://github.com/request/request/pull/1211) Allow 'Host' header instead of 'host' and remember case across redirects (@nylen) +- [#1208](https://github.com/request/request/pull/1208) Improve release script (@nylen) +- [#1213](https://github.com/request/request/pull/1213) Support for custom cookie store (@nylen, @mitsuru) +- [#1197](https://github.com/request/request/pull/1197) Clean up some code around setting the agent (@FredKSchott) +- [#1209](https://github.com/request/request/pull/1209) Improve multipart form append test (@simov) +- [#1207](https://github.com/request/request/pull/1207) Update changelog (@nylen) +- [#1185](https://github.com/request/request/pull/1185) Stream multipart/related bodies (@simov) + +### v2.46.0 (2014/10/23) +- [#1198](https://github.com/request/request/pull/1198) doc for TLS/SSL protocol options (@shawnzhu) +- [#1200](https://github.com/request/request/pull/1200) Add a Gitter chat badge to README.md (@gitter-badger) +- [#1196](https://github.com/request/request/pull/1196) Upgrade taper test reporter to v0.3.0 (@nylen) +- [#1199](https://github.com/request/request/pull/1199) Fix lint error: undeclared var i (@nylen) +- [#1191](https://github.com/request/request/pull/1191) Move self.proxy decision logic out of init and into a helper (@FredKSchott) +- [#1190](https://github.com/request/request/pull/1190) Move _buildRequest() logic back into init (@FredKSchott) +- [#1186](https://github.com/request/request/pull/1186) Support Smarter Unix URL Scheme (@FredKSchott) +- [#1178](https://github.com/request/request/pull/1178) update form documentation for new usage (@FredKSchott) +- [#1180](https://github.com/request/request/pull/1180) Enable no-mixed-requires linting rule (@nylen) +- [#1184](https://github.com/request/request/pull/1184) Don't forward authorization header across redirects to different hosts (@nylen) +- [#1183](https://github.com/request/request/pull/1183) Correct README about pre and postamble CRLF using multipart and not mult... (@netpoetica) +- [#1179](https://github.com/request/request/pull/1179) Lint tests directory (@nylen) +- [#1169](https://github.com/request/request/pull/1169) add metadata for form-data file field (@dotcypress) +- [#1173](https://github.com/request/request/pull/1173) remove optional dependencies (@seanstrom) +- [#1165](https://github.com/request/request/pull/1165) Cleanup event listeners and remove function creation from init (@FredKSchott) +- [#1174](https://github.com/request/request/pull/1174) update the request.cookie docs to have a valid cookie example (@seanstrom) +- [#1168](https://github.com/request/request/pull/1168) create a detach helper and use detach helper in replace of nextTick (@seanstrom) +- [#1171](https://github.com/request/request/pull/1171) in post can send form data and use callback (@MiroRadenovic) +- [#1159](https://github.com/request/request/pull/1159) accept charset for x-www-form-urlencoded content-type (@seanstrom) +- [#1157](https://github.com/request/request/pull/1157) Update README.md: body with json=true (@Rob--W) +- [#1164](https://github.com/request/request/pull/1164) Disable tests/test-timeout.js on Travis (@nylen) +- [#1153](https://github.com/request/request/pull/1153) Document how to run a single test (@nylen) +- [#1144](https://github.com/request/request/pull/1144) adds documentation for the "response" event within the streaming section (@tbuchok) +- [#1162](https://github.com/request/request/pull/1162) Update eslintrc file to no longer allow past errors (@FredKSchott) +- [#1155](https://github.com/request/request/pull/1155) Support/use self everywhere (@seanstrom) +- [#1161](https://github.com/request/request/pull/1161) fix no-use-before-define lint warnings (@emkay) +- [#1156](https://github.com/request/request/pull/1156) adding curly brackets to get rid of lint errors (@emkay) +- [#1151](https://github.com/request/request/pull/1151) Fix localAddress test on OS X (@nylen) +- [#1145](https://github.com/request/request/pull/1145) documentation: fix outdated reference to setCookieSync old name in README (@FredKSchott) +- [#1131](https://github.com/request/request/pull/1131) Update pool documentation (@FredKSchott) +- [#1143](https://github.com/request/request/pull/1143) Rewrite all tests to use tape (@nylen) +- [#1137](https://github.com/request/request/pull/1137) Add ability to specifiy querystring lib in options. (@jgrund) +- [#1138](https://github.com/request/request/pull/1138) allow hostname and port in place of host on uri (@cappslock) +- [#1134](https://github.com/request/request/pull/1134) Fix multiple redirects and `self.followRedirect` (@blakeembrey) +- [#1130](https://github.com/request/request/pull/1130) documentation fix: add note about npm test for contributing (@FredKSchott) +- [#1120](https://github.com/request/request/pull/1120) Support/refactor request setup tunnel (@seanstrom) +- [#1129](https://github.com/request/request/pull/1129) linting fix: convert double quote strings to use single quotes (@FredKSchott) +- [#1124](https://github.com/request/request/pull/1124) linting fix: remove unneccesary semi-colons (@FredKSchott) + +### v2.45.0 (2014/10/06) +- [#1128](https://github.com/request/request/pull/1128) Add test for setCookie regression (@nylen) +- [#1127](https://github.com/request/request/pull/1127) added tests around using objects as values in a query string (@bcoe) +- [#1103](https://github.com/request/request/pull/1103) Support/refactor request constructor (@nylen, @seanstrom) +- [#1119](https://github.com/request/request/pull/1119) add basic linting to request library (@FredKSchott) +- [#1121](https://github.com/request/request/pull/1121) Revert "Explicitly use sync versions of cookie functions" (@nylen) +- [#1118](https://github.com/request/request/pull/1118) linting fix: Restructure bad empty if statement (@FredKSchott) +- [#1117](https://github.com/request/request/pull/1117) Fix a bad check for valid URIs (@FredKSchott) +- [#1113](https://github.com/request/request/pull/1113) linting fix: space out operators (@FredKSchott) +- [#1116](https://github.com/request/request/pull/1116) Fix typo in `noProxyHost` definition (@FredKSchott) +- [#1114](https://github.com/request/request/pull/1114) linting fix: Added a `new` operator that was missing when creating and throwing a new error (@FredKSchott) +- [#1096](https://github.com/request/request/pull/1096) No_proxy support (@samcday) +- [#1107](https://github.com/request/request/pull/1107) linting-fix: remove unused variables (@FredKSchott) +- [#1112](https://github.com/request/request/pull/1112) linting fix: Make return values consistent and more straitforward (@FredKSchott) +- [#1111](https://github.com/request/request/pull/1111) linting fix: authPieces was getting redeclared (@FredKSchott) +- [#1105](https://github.com/request/request/pull/1105) Use strict mode in request (@FredKSchott) +- [#1110](https://github.com/request/request/pull/1110) linting fix: replace lazy '==' with more strict '===' (@FredKSchott) +- [#1109](https://github.com/request/request/pull/1109) linting fix: remove function call from if-else conditional statement (@FredKSchott) +- [#1102](https://github.com/request/request/pull/1102) Fix to allow setting a `requester` on recursive calls to `request.defaults` (@tikotzky) +- [#1095](https://github.com/request/request/pull/1095) Tweaking engines in package.json (@pdehaan) +- [#1082](https://github.com/request/request/pull/1082) Forward the socket event from the httpModule request (@seanstrom) +- [#972](https://github.com/request/request/pull/972) Clarify gzip handling in the README (@kevinoid) +- [#1089](https://github.com/request/request/pull/1089) Mention that encoding defaults to utf8, not Buffer (@stuartpb) +- [#1088](https://github.com/request/request/pull/1088) Fix cookie example in README.md and make it more clear (@pipi32167) +- [#1027](https://github.com/request/request/pull/1027) Add support for multipart form data in request options. (@crocket) +- [#1076](https://github.com/request/request/pull/1076) use Request.abort() to abort the request when the request has timed-out (@seanstrom) +- [#1068](https://github.com/request/request/pull/1068) add optional postamble required by .NET multipart requests (@netpoetica) + +### v2.43.0 (2014/09/18) +- [#1057](https://github.com/request/request/pull/1057) Defaults should not overwrite defined options (@davidwood) +- [#1046](https://github.com/request/request/pull/1046) Propagate datastream errors, useful in case gzip fails. (@ZJONSSON, @Janpot) +- [#1063](https://github.com/request/request/pull/1063) copy the input headers object #1060 (@finnp) +- [#1031](https://github.com/request/request/pull/1031) Explicitly use sync versions of cookie functions (@ZJONSSON) +- [#1056](https://github.com/request/request/pull/1056) Fix redirects when passing url.parse(x) as URL to convenience method (@nylen) + +### v2.42.0 (2014/09/04) +- [#1053](https://github.com/request/request/pull/1053) Fix #1051 Parse auth properly when using non-tunneling proxy (@isaacs) + +### v2.41.0 (2014/09/04) +- [#1050](https://github.com/request/request/pull/1050) Pass whitelisted headers to tunneling proxy. Organize all tunneling logic. (@isaacs, @Feldhacker) +- [#1035](https://github.com/request/request/pull/1035) souped up nodei.co badge (@rvagg) +- [#1048](https://github.com/request/request/pull/1048) Aws is now possible over a proxy (@steven-aerts) +- [#1039](https://github.com/request/request/pull/1039) extract out helper functions to a helper file (@seanstrom) +- [#1021](https://github.com/request/request/pull/1021) Support/refactor indexjs (@seanstrom) +- [#1033](https://github.com/request/request/pull/1033) Improve and document debug options (@nylen) +- [#1034](https://github.com/request/request/pull/1034) Fix readme headings (@nylen) +- [#1030](https://github.com/request/request/pull/1030) Allow recursive request.defaults (@tikotzky) +- [#1029](https://github.com/request/request/pull/1029) Fix a couple of typos (@nylen) +- [#675](https://github.com/request/request/pull/675) Checking for SSL fault on connection before reading SSL properties (@VRMink) +- [#989](https://github.com/request/request/pull/989) Added allowRedirect function. Should return true if redirect is allowed or false otherwise (@doronin) +- [#1025](https://github.com/request/request/pull/1025) [fixes #1023] Set self._ended to true once response has ended (@mridgway) +- [#1020](https://github.com/request/request/pull/1020) Add back removed debug metadata (@FredKSchott) +- [#1008](https://github.com/request/request/pull/1008) Moving to module instead of cutomer buffer concatenation. (@mikeal) +- [#770](https://github.com/request/request/pull/770) Added dependency badge for README file; (@timgluz, @mafintosh, @lalitkapoor, @stash, @bobyrizov) +- [#1016](https://github.com/request/request/pull/1016) toJSON no longer results in an infinite loop, returns simple objects (@FredKSchott) +- [#1018](https://github.com/request/request/pull/1018) Remove pre-0.4.4 HTTPS fix (@mmalecki) +- [#1006](https://github.com/request/request/pull/1006) Migrate to caseless, fixes #1001 (@mikeal) +- [#995](https://github.com/request/request/pull/995) Fix parsing array of objects (@sjonnet19) +- [#999](https://github.com/request/request/pull/999) Fix fallback for browserify for optional modules. (@eiriksm) +- [#996](https://github.com/request/request/pull/996) Wrong oauth signature when multiple same param keys exist [updated] (@bengl) + +### v2.40.0 (2014/08/06) +- [#992](https://github.com/request/request/pull/992) Fix security vulnerability. Update qs (@poeticninja) +- [#988](https://github.com/request/request/pull/988) “--” -> “—” (@upisfree) +- [#987](https://github.com/request/request/pull/987) Show optional modules as being loaded by the module that reqeusted them (@iarna) + +### v2.39.0 (2014/07/24) +- [#976](https://github.com/request/request/pull/976) Update README.md (@pvoznenko) + +### v2.38.0 (2014/07/22) +- [#952](https://github.com/request/request/pull/952) Adding support to client certificate with proxy use case (@ofirshaked) +- [#884](https://github.com/request/request/pull/884) Documented tough-cookie installation. (@wbyoung) +- [#935](https://github.com/request/request/pull/935) Correct repository url (@fritx) +- [#963](https://github.com/request/request/pull/963) Update changelog (@nylen) +- [#960](https://github.com/request/request/pull/960) Support gzip with encoding on node pre-v0.9.4 (@kevinoid) +- [#953](https://github.com/request/request/pull/953) Add async Content-Length computation when using form-data (@LoicMahieu) +- [#844](https://github.com/request/request/pull/844) Add support for HTTP[S]_PROXY environment variables. Fixes #595. (@jvmccarthy) +- [#946](https://github.com/request/request/pull/946) defaults: merge headers (@aj0strow) + +### v2.37.0 (2014/07/07) +- [#957](https://github.com/request/request/pull/957) Silence EventEmitter memory leak warning #311 (@watson) +- [#955](https://github.com/request/request/pull/955) check for content-length header before setting it in nextTick (@camilleanne) +- [#951](https://github.com/request/request/pull/951) Add support for gzip content decoding (@kevinoid) +- [#949](https://github.com/request/request/pull/949) Manually enter querystring in form option (@charlespwd) +- [#944](https://github.com/request/request/pull/944) Make request work with browserify (@eiriksm) +- [#943](https://github.com/request/request/pull/943) New mime module (@eiriksm) +- [#927](https://github.com/request/request/pull/927) Bump version of hawk dep. (@samccone) +- [#907](https://github.com/request/request/pull/907) append secureOptions to poolKey (@medovob) + +### v2.35.0 (2014/05/17) +- [#901](https://github.com/request/request/pull/901) Fixes #555 (@pigulla) +- [#897](https://github.com/request/request/pull/897) merge with default options (@vohof) +- [#891](https://github.com/request/request/pull/891) fixes 857 - options object is mutated by calling request (@lalitkapoor) +- [#869](https://github.com/request/request/pull/869) Pipefilter test (@tgohn) +- [#866](https://github.com/request/request/pull/866) Fix typo (@dandv) +- [#861](https://github.com/request/request/pull/861) Add support for RFC 6750 Bearer Tokens (@phedny) +- [#809](https://github.com/request/request/pull/809) upgrade tunnel-proxy to 0.4.0 (@ksato9700) +- [#850](https://github.com/request/request/pull/850) Fix word consistency in readme (@0xNobody) +- [#810](https://github.com/request/request/pull/810) add some exposition to mpu example in README.md (@mikermcneil) +- [#840](https://github.com/request/request/pull/840) improve error reporting for invalid protocols (@FND) +- [#821](https://github.com/request/request/pull/821) added secureOptions back (@nw) +- [#815](https://github.com/request/request/pull/815) Create changelog based on pull requests (@lalitkapoor) + +### v2.34.0 (2014/02/18) +- [#516](https://github.com/request/request/pull/516) UNIX Socket URL Support (@lyuzashi) +- [#801](https://github.com/request/request/pull/801) 794 ignore cookie parsing and domain errors (@lalitkapoor) +- [#802](https://github.com/request/request/pull/802) Added the Apache license to the package.json. (@keskival) +- [#793](https://github.com/request/request/pull/793) Adds content-length calculation when submitting forms using form-data li... (@Juul) +- [#785](https://github.com/request/request/pull/785) Provide ability to override content-type when `json` option used (@vvo) +- [#781](https://github.com/request/request/pull/781) simpler isReadStream function (@joaojeronimo) + +### v2.32.0 (2014/01/16) +- [#767](https://github.com/request/request/pull/767) Use tough-cookie CookieJar sync API (@stash) +- [#764](https://github.com/request/request/pull/764) Case-insensitive authentication scheme (@bobyrizov) +- [#763](https://github.com/request/request/pull/763) Upgrade tough-cookie to 0.10.0 (@stash) +- [#744](https://github.com/request/request/pull/744) Use Cookie.parse (@lalitkapoor) +- [#757](https://github.com/request/request/pull/757) require aws-sign2 (@mafintosh) + +### v2.31.0 (2014/01/08) +- [#645](https://github.com/request/request/pull/645) update twitter api url to v1.1 (@mick) +- [#746](https://github.com/request/request/pull/746) README: Markdown code highlight (@weakish) +- [#745](https://github.com/request/request/pull/745) updating setCookie example to make it clear that the callback is required (@emkay) +- [#742](https://github.com/request/request/pull/742) Add note about JSON output body type (@iansltx) +- [#741](https://github.com/request/request/pull/741) README example is using old cookie jar api (@emkay) +- [#736](https://github.com/request/request/pull/736) Fix callback arguments documentation (@mmalecki) +- [#732](https://github.com/request/request/pull/732) JSHINT: Creating global 'for' variable. Should be 'for (var ...'. (@Fritz-Lium) +- [#730](https://github.com/request/request/pull/730) better HTTP DIGEST support (@dai-shi) +- [#728](https://github.com/request/request/pull/728) Fix TypeError when calling request.cookie (@scarletmeow) +- [#727](https://github.com/request/request/pull/727) fix requester bug (@jchris) +- [#724](https://github.com/request/request/pull/724) README.md: add custom HTTP Headers example. (@tcort) +- [#719](https://github.com/request/request/pull/719) Made a comment gender neutral. (@unsetbit) +- [#715](https://github.com/request/request/pull/715) Request.multipart no longer crashes when header 'Content-type' present (@pastaclub) +- [#710](https://github.com/request/request/pull/710) Fixing listing in callback part of docs. (@lukasz-zak) +- [#696](https://github.com/request/request/pull/696) Edited README.md for formatting and clarity of phrasing (@Zearin) +- [#694](https://github.com/request/request/pull/694) Typo in README (@VRMink) +- [#690](https://github.com/request/request/pull/690) Handle blank password in basic auth. (@diversario) +- [#682](https://github.com/request/request/pull/682) Optional dependencies (@Turbo87) +- [#683](https://github.com/request/request/pull/683) Travis CI support (@Turbo87) +- [#674](https://github.com/request/request/pull/674) change cookie module,to tough-cookie.please check it . (@sxyizhiren) +- [#666](https://github.com/request/request/pull/666) make `ciphers` and `secureProtocol` to work in https request (@richarddong) +- [#656](https://github.com/request/request/pull/656) Test case for #304. (@diversario) +- [#662](https://github.com/request/request/pull/662) option.tunnel to explicitly disable tunneling (@seanmonstar) +- [#659](https://github.com/request/request/pull/659) fix failure when running with NODE_DEBUG=request, and a test for that (@jrgm) +- [#630](https://github.com/request/request/pull/630) Send random cnonce for HTTP Digest requests (@wprl) +- [#619](https://github.com/request/request/pull/619) decouple things a bit (@joaojeronimo) +- [#613](https://github.com/request/request/pull/613) Fixes #583, moved initialization of self.uri.pathname (@lexander) +- [#605](https://github.com/request/request/pull/605) Only include ":" + pass in Basic Auth if it's defined (fixes #602) (@bendrucker) +- [#596](https://github.com/request/request/pull/596) Global agent is being used when pool is specified (@Cauldrath) +- [#594](https://github.com/request/request/pull/594) Emit complete event when there is no callback (@RomainLK) +- [#601](https://github.com/request/request/pull/601) Fixed a small typo (@michalstanko) +- [#589](https://github.com/request/request/pull/589) Prevent setting headers after they are sent (@geek) +- [#587](https://github.com/request/request/pull/587) Global cookie jar disabled by default (@threepointone) +- [#544](https://github.com/request/request/pull/544) Update http-signature version. (@davidlehn) +- [#581](https://github.com/request/request/pull/581) Fix spelling of "ignoring." (@bigeasy) +- [#568](https://github.com/request/request/pull/568) use agentOptions to create agent when specified in request (@SamPlacette) +- [#564](https://github.com/request/request/pull/564) Fix redirections (@criloz) +- [#541](https://github.com/request/request/pull/541) The exported request function doesn't have an auth method (@tschaub) +- [#542](https://github.com/request/request/pull/542) Expose Request class (@regality) +- [#536](https://github.com/request/request/pull/536) Allow explicitly empty user field for basic authentication. (@mikeando) +- [#532](https://github.com/request/request/pull/532) fix typo (@fredericosilva) +- [#497](https://github.com/request/request/pull/497) Added redirect event (@Cauldrath) +- [#503](https://github.com/request/request/pull/503) Fix basic auth for passwords that contain colons (@tonistiigi) +- [#521](https://github.com/request/request/pull/521) Improving test-localAddress.js (@noway) +- [#529](https://github.com/request/request/pull/529) dependencies versions bump (@jodaka) +- [#523](https://github.com/request/request/pull/523) Updating dependencies (@noway) +- [#520](https://github.com/request/request/pull/520) Fixing test-tunnel.js (@noway) +- [#519](https://github.com/request/request/pull/519) Update internal path state on post-creation QS changes (@jblebrun) +- [#510](https://github.com/request/request/pull/510) Add HTTP Signature support. (@davidlehn) +- [#502](https://github.com/request/request/pull/502) Fix POST (and probably other) requests that are retried after 401 Unauthorized (@nylen) +- [#508](https://github.com/request/request/pull/508) Honor the .strictSSL option when using proxies (tunnel-agent) (@jhs) +- [#512](https://github.com/request/request/pull/512) Make password optional to support the format: http://username@hostname/ (@pajato1) +- [#513](https://github.com/request/request/pull/513) add 'localAddress' support (@yyfrankyy) +- [#498](https://github.com/request/request/pull/498) Moving response emit above setHeaders on destination streams (@kenperkins) +- [#490](https://github.com/request/request/pull/490) Empty response body (3-rd argument) must be passed to callback as an empty string (@Olegas) +- [#479](https://github.com/request/request/pull/479) Changing so if Accept header is explicitly set, sending json does not ov... (@RoryH) +- [#475](https://github.com/request/request/pull/475) Use `unescape` from `querystring` (@shimaore) +- [#473](https://github.com/request/request/pull/473) V0.10 compat (@isaacs) +- [#471](https://github.com/request/request/pull/471) Using querystring library from visionmedia (@kbackowski) +- [#461](https://github.com/request/request/pull/461) Strip the UTF8 BOM from a UTF encoded response (@kppullin) +- [#460](https://github.com/request/request/pull/460) hawk 0.10.0 (@hueniverse) +- [#462](https://github.com/request/request/pull/462) if query params are empty, then request path shouldn't end with a '?' (merges cleanly now) (@jaipandya) +- [#456](https://github.com/request/request/pull/456) hawk 0.9.0 (@hueniverse) +- [#429](https://github.com/request/request/pull/429) Copy options before adding callback. (@nrn, @nfriedly, @youurayy, @jplock, @kapetan, @landeiro, @othiym23, @mmalecki) +- [#454](https://github.com/request/request/pull/454) Destroy the response if present when destroying the request (clean merge) (@mafintosh) +- [#310](https://github.com/request/request/pull/310) Twitter Oauth Stuff Out of Date; Now Updated (@joemccann, @isaacs, @mscdex) +- [#413](https://github.com/request/request/pull/413) rename googledoodle.png to .jpg (@nfriedly, @youurayy, @jplock, @kapetan, @landeiro, @othiym23, @mmalecki) +- [#448](https://github.com/request/request/pull/448) Convenience method for PATCH (@mloar) +- [#444](https://github.com/request/request/pull/444) protect against double callbacks on error path (@spollack) +- [#433](https://github.com/request/request/pull/433) Added support for HTTPS cert & key (@mmalecki) +- [#430](https://github.com/request/request/pull/430) Respect specified {Host,host} headers, not just {host} (@andrewschaaf) +- [#415](https://github.com/request/request/pull/415) Fixed a typo. (@jerem) +- [#338](https://github.com/request/request/pull/338) Add more auth options, including digest support (@nylen) +- [#403](https://github.com/request/request/pull/403) Optimize environment lookup to happen once only (@mmalecki) +- [#398](https://github.com/request/request/pull/398) Add more reporting to tests (@mmalecki) +- [#388](https://github.com/request/request/pull/388) Ensure "safe" toJSON doesn't break EventEmitters (@othiym23) +- [#381](https://github.com/request/request/pull/381) Resolving "Invalid signature. Expected signature base string: " (@landeiro) +- [#380](https://github.com/request/request/pull/380) Fixes missing host header on retried request when using forever agent (@mac-) +- [#376](https://github.com/request/request/pull/376) Headers lost on redirect (@kapetan) +- [#375](https://github.com/request/request/pull/375) Fix for missing oauth_timestamp parameter (@jplock) +- [#374](https://github.com/request/request/pull/374) Correct Host header for proxy tunnel CONNECT (@youurayy) +- [#370](https://github.com/request/request/pull/370) Twitter reverse auth uses x_auth_mode not x_auth_type (@drudge) +- [#369](https://github.com/request/request/pull/369) Don't remove x_auth_mode for Twitter reverse auth (@drudge) +- [#344](https://github.com/request/request/pull/344) Make AWS auth signing find headers correctly (@nlf) +- [#363](https://github.com/request/request/pull/363) rfc3986 on base_uri, now passes tests (@jeffmarshall) +- [#362](https://github.com/request/request/pull/362) Running `rfc3986` on `base_uri` in `oauth.hmacsign` instead of just `encodeURIComponent` (@jeffmarshall) +- [#361](https://github.com/request/request/pull/361) Don't create a Content-Length header if we already have it set (@danjenkins) +- [#360](https://github.com/request/request/pull/360) Delete self._form along with everything else on redirect (@jgautier) +- [#355](https://github.com/request/request/pull/355) stop sending erroneous headers on redirected requests (@azylman) +- [#332](https://github.com/request/request/pull/332) Fix #296 - Only set Content-Type if body exists (@Marsup) +- [#343](https://github.com/request/request/pull/343) Allow AWS to work in more situations, added a note in the README on its usage (@nlf) +- [#320](https://github.com/request/request/pull/320) request.defaults() doesn't need to wrap jar() (@StuartHarris) +- [#322](https://github.com/request/request/pull/322) Fix + test for piped into request bumped into redirect. #321 (@alexindigo) +- [#326](https://github.com/request/request/pull/326) Do not try to remove listener from an undefined connection (@CartoDB) +- [#318](https://github.com/request/request/pull/318) Pass servername to tunneling secure socket creation (@isaacs) +- [#317](https://github.com/request/request/pull/317) Workaround for #313 (@isaacs) +- [#293](https://github.com/request/request/pull/293) Allow parser errors to bubble up to request (@mscdex) +- [#290](https://github.com/request/request/pull/290) A test for #289 (@isaacs) +- [#280](https://github.com/request/request/pull/280) Like in node.js print options if NODE_DEBUG contains the word request (@Filirom1) +- [#207](https://github.com/request/request/pull/207) Fix #206 Change HTTP/HTTPS agent when redirecting between protocols (@isaacs) +- [#214](https://github.com/request/request/pull/214) documenting additional behavior of json option (@jphaas, @vpulim) +- [#272](https://github.com/request/request/pull/272) Boundary begins with CRLF? (@elspoono, @timshadel, @naholyr, @nanodocumet, @TehShrike) +- [#284](https://github.com/request/request/pull/284) Remove stray `console.log()` call in multipart generator. (@bcherry) +- [#241](https://github.com/request/request/pull/241) Composability updates suggested by issue #239 (@polotek) +- [#282](https://github.com/request/request/pull/282) OAuth Authorization header contains non-"oauth_" parameters (@jplock) +- [#279](https://github.com/request/request/pull/279) fix tests with boundary by injecting boundry from header (@benatkin) +- [#273](https://github.com/request/request/pull/273) Pipe back pressure issue (@mafintosh) +- [#268](https://github.com/request/request/pull/268) I'm not OCD seriously (@TehShrike) +- [#263](https://github.com/request/request/pull/263) Bug in OAuth key generation for sha1 (@nanodocumet) +- [#265](https://github.com/request/request/pull/265) uncaughtException when redirected to invalid URI (@naholyr) +- [#262](https://github.com/request/request/pull/262) JSON test should check for equality (@timshadel) +- [#261](https://github.com/request/request/pull/261) Setting 'pool' to 'false' does NOT disable Agent pooling (@timshadel) +- [#249](https://github.com/request/request/pull/249) Fix for the fix of your (closed) issue #89 where self.headers[content-length] is set to 0 for all methods (@sethbridges, @polotek, @zephrax, @jeromegn) +- [#255](https://github.com/request/request/pull/255) multipart allow body === '' ( the empty string ) (@Filirom1) +- [#260](https://github.com/request/request/pull/260) fixed just another leak of 'i' (@sreuter) +- [#246](https://github.com/request/request/pull/246) Fixing the set-cookie header (@jeromegn) +- [#243](https://github.com/request/request/pull/243) Dynamic boundary (@zephrax) +- [#240](https://github.com/request/request/pull/240) don't error when null is passed for options (@polotek) +- [#211](https://github.com/request/request/pull/211) Replace all occurrences of special chars in RFC3986 (@chriso, @vpulim) +- [#224](https://github.com/request/request/pull/224) Multipart content-type change (@janjongboom) +- [#217](https://github.com/request/request/pull/217) need to use Authorization (titlecase) header with Tumblr OAuth (@visnup) +- [#203](https://github.com/request/request/pull/203) Fix cookie and redirect bugs and add auth support for HTTPS tunnel (@vpulim) +- [#199](https://github.com/request/request/pull/199) Tunnel (@isaacs) +- [#198](https://github.com/request/request/pull/198) Bugfix on forever usage of util.inherits (@isaacs) +- [#197](https://github.com/request/request/pull/197) Make ForeverAgent work with HTTPS (@isaacs) +- [#193](https://github.com/request/request/pull/193) Fixes GH-119 (@goatslacker) +- [#188](https://github.com/request/request/pull/188) Add abort support to the returned request (@itay) +- [#176](https://github.com/request/request/pull/176) Querystring option (@csainty) +- [#182](https://github.com/request/request/pull/182) Fix request.defaults to support (uri, options, callback) api (@twilson63) +- [#180](https://github.com/request/request/pull/180) Modified the post, put, head and del shortcuts to support uri optional param (@twilson63) +- [#179](https://github.com/request/request/pull/179) fix to add opts in .pipe(stream, opts) (@substack) +- [#177](https://github.com/request/request/pull/177) Issue #173 Support uri as first and optional config as second argument (@twilson63) +- [#170](https://github.com/request/request/pull/170) can't create a cookie in a wrapped request (defaults) (@fabianonunes) +- [#168](https://github.com/request/request/pull/168) Picking off an EasyFix by adding some missing mimetypes. (@serby) +- [#161](https://github.com/request/request/pull/161) Fix cookie jar/headers.cookie collision (#125) (@papandreou) +- [#162](https://github.com/request/request/pull/162) Fix issue #159 (@dpetukhov) +- [#90](https://github.com/request/request/pull/90) add option followAllRedirects to follow post/put redirects (@jroes) +- [#148](https://github.com/request/request/pull/148) Retry Agent (@thejh) +- [#146](https://github.com/request/request/pull/146) Multipart should respect content-type if previously set (@apeace) +- [#144](https://github.com/request/request/pull/144) added "form" option to readme (@petejkim) +- [#133](https://github.com/request/request/pull/133) Fixed cookies parsing (@afanasy) +- [#135](https://github.com/request/request/pull/135) host vs hostname (@iangreenleaf) +- [#132](https://github.com/request/request/pull/132) return the body as a Buffer when encoding is set to null (@jahewson) +- [#112](https://github.com/request/request/pull/112) Support using a custom http-like module (@jhs) +- [#104](https://github.com/request/request/pull/104) Cookie handling contains bugs (@janjongboom) +- [#121](https://github.com/request/request/pull/121) Another patch for cookie handling regression (@jhurliman) +- [#117](https://github.com/request/request/pull/117) Remove the global `i` (@3rd-Eden) +- [#110](https://github.com/request/request/pull/110) Update to Iris Couch URL (@jhs) +- [#86](https://github.com/request/request/pull/86) Can't post binary to multipart requests (@kkaefer) +- [#105](https://github.com/request/request/pull/105) added test for proxy option. (@dominictarr) +- [#102](https://github.com/request/request/pull/102) Implemented cookies - closes issue 82: https://github.com/mikeal/request/issues/82 (@alessioalex) +- [#97](https://github.com/request/request/pull/97) Typo in previous pull causes TypeError in non-0.5.11 versions (@isaacs) +- [#96](https://github.com/request/request/pull/96) Authless parsed url host support (@isaacs) +- [#81](https://github.com/request/request/pull/81) Enhance redirect handling (@danmactough) +- [#78](https://github.com/request/request/pull/78) Don't try to do strictSSL for non-ssl connections (@isaacs) +- [#76](https://github.com/request/request/pull/76) Bug when a request fails and a timeout is set (@Marsup) +- [#70](https://github.com/request/request/pull/70) add test script to package.json (@isaacs, @aheckmann) +- [#73](https://github.com/request/request/pull/73) Fix #71 Respect the strictSSL flag (@isaacs) +- [#69](https://github.com/request/request/pull/69) Flatten chunked requests properly (@isaacs) +- [#67](https://github.com/request/request/pull/67) fixed global variable leaks (@aheckmann) +- [#66](https://github.com/request/request/pull/66) Do not overwrite established content-type headers for read stream deliver (@voodootikigod) +- [#53](https://github.com/request/request/pull/53) Parse json: Issue #51 (@benatkin) +- [#45](https://github.com/request/request/pull/45) Added timeout option (@mbrevoort) +- [#35](https://github.com/request/request/pull/35) The "end" event isn't emitted for some responses (@voxpelli) +- [#31](https://github.com/request/request/pull/31) Error on piping a request to a destination (@tobowers) \ No newline at end of file diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/LICENSE b/pype/premiere/extensions/com.pype.avalon/node_modules/request/LICENSE new file mode 100644 index 0000000000..a4a9aee0c2 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/LICENSE @@ -0,0 +1,55 @@ +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: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +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 + +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 \ No newline at end of file diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/README.md b/pype/premiere/extensions/com.pype.avalon/node_modules/request/README.md new file mode 100644 index 0000000000..2317391149 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/README.md @@ -0,0 +1,1115 @@ + +# Request - Simplified HTTP client + +[![npm package](https://nodei.co/npm/request.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/request/) + +[![Build status](https://img.shields.io/travis/request/request/master.svg?style=flat-square)](https://travis-ci.org/request/request) +[![Coverage](https://img.shields.io/codecov/c/github/request/request.svg?style=flat-square)](https://codecov.io/github/request/request?branch=master) +[![Coverage](https://img.shields.io/coveralls/request/request.svg?style=flat-square)](https://coveralls.io/r/request/request) +[![Dependency Status](https://img.shields.io/david/request/request.svg?style=flat-square)](https://david-dm.org/request/request) +[![Known Vulnerabilities](https://snyk.io/test/npm/request/badge.svg?style=flat-square)](https://snyk.io/test/npm/request) +[![Gitter](https://img.shields.io/badge/gitter-join_chat-blue.svg?style=flat-square)](https://gitter.im/request/request?utm_source=badge) + + +## Super simple to use + +Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default. + +```js +var request = require('request'); +request('http://www.google.com', function (error, response, body) { + console.log('error:', error); // Print the error if one occurred + console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received + console.log('body:', body); // Print the HTML for the Google homepage. +}); +``` + + +## Table of contents + +- [Streaming](#streaming) +- [Forms](#forms) +- [HTTP Authentication](#http-authentication) +- [Custom HTTP Headers](#custom-http-headers) +- [OAuth Signing](#oauth-signing) +- [Proxies](#proxies) +- [Unix Domain Sockets](#unix-domain-sockets) +- [TLS/SSL Protocol](#tlsssl-protocol) +- [Support for HAR 1.2](#support-for-har-12) +- [**All Available Options**](#requestoptions-callback) + +Request also offers [convenience methods](#convenience-methods) like +`request.defaults` and `request.post`, and there are +lots of [usage examples](#examples) and several +[debugging techniques](#debugging). + + +--- + + +## Streaming + +You can stream any response to a file stream. + +```js +request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) +``` + +You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types (in this case `application/json`) and use the proper `content-type` in the PUT request (if the headers don’t already provide one). + +```js +fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')) +``` + +Request can also `pipe` to itself. When doing so, `content-type` and `content-length` are preserved in the PUT headers. + +```js +request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png')) +``` + +Request emits a "response" event when a response is received. The `response` argument will be an instance of [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage). + +```js +request + .get('http://google.com/img.png') + .on('response', function(response) { + console.log(response.statusCode) // 200 + console.log(response.headers['content-type']) // 'image/png' + }) + .pipe(request.put('http://mysite.com/img.png')) +``` + +To easily handle errors when streaming requests, listen to the `error` event before piping: + +```js +request + .get('http://mysite.com/doodle.png') + .on('error', function(err) { + console.log(err) + }) + .pipe(fs.createWriteStream('doodle.png')) +``` + +Now let’s get fancy. + +```js +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + if (req.method === 'PUT') { + req.pipe(request.put('http://mysite.com/doodle.png')) + } else if (req.method === 'GET' || req.method === 'HEAD') { + request.get('http://mysite.com/doodle.png').pipe(resp) + } + } +}) +``` + +You can also `pipe()` from `http.ServerRequest` instances, as well as to `http.ServerResponse` instances. The HTTP method, headers, and entity-body data will be sent. Which means that, if you don't really care about security, you can do: + +```js +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + var x = request('http://mysite.com/doodle.png') + req.pipe(x) + x.pipe(resp) + } +}) +``` + +And since `pipe()` returns the destination stream in ≥ Node 0.5.x you can do one line proxying. :) + +```js +req.pipe(request('http://mysite.com/doodle.png')).pipe(resp) +``` + +Also, none of this new functionality conflicts with requests previous features, it just expands them. + +```js +var r = request.defaults({'proxy':'http://localproxy.com'}) + +http.createServer(function (req, resp) { + if (req.url === '/doodle.png') { + r.get('http://google.com/doodle.png').pipe(resp) + } +}) +``` + +You can still use intermediate proxies, the requests will still follow HTTP forwards, etc. + +[back to top](#table-of-contents) + + +--- + + +## Forms + +`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API. + + +#### application/x-www-form-urlencoded (URL-Encoded Forms) + +URL-encoded forms are simple. + +```js +request.post('http://service.com/upload', {form:{key:'value'}}) +// or +request.post('http://service.com/upload').form({key:'value'}) +// or +request.post({url:'http://service.com/upload', form: {key:'value'}}, function(err,httpResponse,body){ /* ... */ }) +``` + + +#### multipart/form-data (Multipart Form Uploads) + +For `multipart/form-data` we use the [form-data](https://github.com/form-data/form-data) library by [@felixge](https://github.com/felixge). For the most cases, you can pass your upload form data via the `formData` option. + + +```js +var formData = { + // Pass a simple key-value pair + my_field: 'my_value', + // Pass data via Buffers + my_buffer: new Buffer([1, 2, 3]), + // Pass data via Streams + my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), + // Pass multiple values /w an Array + attachments: [ + fs.createReadStream(__dirname + '/attachment1.jpg'), + fs.createReadStream(__dirname + '/attachment2.jpg') + ], + // Pass optional meta-data with an 'options' object with style: {value: DATA, options: OPTIONS} + // Use case: for some types of streams, you'll need to provide "file"-related information manually. + // See the `form-data` README for more information about options: https://github.com/form-data/form-data + custom_file: { + value: fs.createReadStream('/dev/urandom'), + options: { + filename: 'topsecret.jpg', + contentType: 'image/jpeg' + } + } +}; +request.post({url:'http://service.com/upload', formData: formData}, function optionalCallback(err, httpResponse, body) { + if (err) { + return console.error('upload failed:', err); + } + console.log('Upload successful! Server responded with:', body); +}); +``` + +For advanced cases, you can access the form-data object itself via `r.form()`. This can be modified until the request is fired on the next cycle of the event-loop. (Note that this calling `form()` will clear the currently set form data for that request.) + +```js +// NOTE: Advanced use-case, for normal use see 'formData' usage above +var r = request.post('http://service.com/upload', function optionalCallback(err, httpResponse, body) {...}) +var form = r.form(); +form.append('my_field', 'my_value'); +form.append('my_buffer', new Buffer([1, 2, 3])); +form.append('custom_file', fs.createReadStream(__dirname + '/unicycle.jpg'), {filename: 'unicycle.jpg'}); +``` +See the [form-data README](https://github.com/form-data/form-data) for more information & examples. + + +#### multipart/related + +Some variations in different HTTP implementations require a newline/CRLF before, after, or both before and after the boundary of a `multipart/related` request (using the multipart option). This has been observed in the .NET WebAPI version 4.0. You can turn on a boundary preambleCRLF or postamble by passing them as `true` to your request options. + +```js + request({ + method: 'PUT', + preambleCRLF: true, + postambleCRLF: true, + uri: 'http://service.com/upload', + multipart: [ + { + 'content-type': 'application/json', + body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + }, + { body: 'I am an attachment' }, + { body: fs.createReadStream('image.png') } + ], + // alternatively pass an object containing additional options + multipart: { + chunked: false, + data: [ + { + 'content-type': 'application/json', + body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + }, + { body: 'I am an attachment' } + ] + } + }, + function (error, response, body) { + if (error) { + return console.error('upload failed:', error); + } + console.log('Upload successful! Server responded with:', body); + }) +``` + +[back to top](#table-of-contents) + + +--- + + +## HTTP Authentication + +```js +request.get('http://some.server.com/').auth('username', 'password', false); +// or +request.get('http://some.server.com/', { + 'auth': { + 'user': 'username', + 'pass': 'password', + 'sendImmediately': false + } +}); +// or +request.get('http://some.server.com/').auth(null, null, true, 'bearerToken'); +// or +request.get('http://some.server.com/', { + 'auth': { + 'bearer': 'bearerToken' + } +}); +``` + +If passed as an option, `auth` should be a hash containing values: + +- `user` || `username` +- `pass` || `password` +- `sendImmediately` (optional) +- `bearer` (optional) + +The method form takes parameters +`auth(username, password, sendImmediately, bearer)`. + +`sendImmediately` defaults to `true`, which causes a basic or bearer +authentication header to be sent. If `sendImmediately` is `false`, then +`request` will retry with a proper authentication header after receiving a +`401` response from the server (which must contain a `WWW-Authenticate` header +indicating the required authentication method). + +Note that you can also specify basic authentication using the URL itself, as +detailed in [RFC 1738](http://www.ietf.org/rfc/rfc1738.txt). Simply pass the +`user:password` before the host with an `@` sign: + +```js +var username = 'username', + password = 'password', + url = 'http://' + username + ':' + password + '@some.server.com'; + +request({url: url}, function (error, response, body) { + // Do more stuff with 'body' here +}); +``` + +Digest authentication is supported, but it only works with `sendImmediately` +set to `false`; otherwise `request` will send basic authentication on the +initial request, which will probably cause the request to fail. + +Bearer authentication is supported, and is activated when the `bearer` value is +available. The value may be either a `String` or a `Function` returning a +`String`. Using a function to supply the bearer token is particularly useful if +used in conjunction with `defaults` to allow a single function to supply the +last known token at the time of sending a request, or to compute one on the fly. + +[back to top](#table-of-contents) + + +--- + + +## Custom HTTP Headers + +HTTP Headers, such as `User-Agent`, can be set in the `options` object. +In the example below, we call the github API to find out the number +of stars and forks for the request repository. This requires a +custom `User-Agent` header as well as https. + +```js +var request = require('request'); + +var options = { + url: 'https://api.github.com/repos/request/request', + headers: { + 'User-Agent': 'request' + } +}; + +function callback(error, response, body) { + if (!error && response.statusCode == 200) { + var info = JSON.parse(body); + console.log(info.stargazers_count + " Stars"); + console.log(info.forks_count + " Forks"); + } +} + +request(options, callback); +``` + +[back to top](#table-of-contents) + + +--- + + +## OAuth Signing + +[OAuth version 1.0](https://tools.ietf.org/html/rfc5849) is supported. The +default signing algorithm is +[HMAC-SHA1](https://tools.ietf.org/html/rfc5849#section-3.4.2): + +```js +// OAuth1.0 - 3-legged server side flow (Twitter example) +// step 1 +var qs = require('querystring') + , oauth = + { callback: 'http://mysite.com/callback/' + , consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + } + , url = 'https://api.twitter.com/oauth/request_token' + ; +request.post({url:url, oauth:oauth}, function (e, r, body) { + // Ideally, you would take the body in the response + // and construct a URL that a user clicks on (like a sign in button). + // The verifier is only available in the response after a user has + // verified with twitter that they are authorizing your app. + + // step 2 + var req_data = qs.parse(body) + var uri = 'https://api.twitter.com/oauth/authenticate' + + '?' + qs.stringify({oauth_token: req_data.oauth_token}) + // redirect the user to the authorize uri + + // step 3 + // after the user is redirected back to your server + var auth_data = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: auth_data.oauth_token + , token_secret: req_data.oauth_token_secret + , verifier: auth_data.oauth_verifier + } + , url = 'https://api.twitter.com/oauth/access_token' + ; + request.post({url:url, oauth:oauth}, function (e, r, body) { + // ready to make signed requests on behalf of the user + var perm_data = qs.parse(body) + , oauth = + { consumer_key: CONSUMER_KEY + , consumer_secret: CONSUMER_SECRET + , token: perm_data.oauth_token + , token_secret: perm_data.oauth_token_secret + } + , url = 'https://api.twitter.com/1.1/users/show.json' + , qs = + { screen_name: perm_data.screen_name + , user_id: perm_data.user_id + } + ; + request.get({url:url, oauth:oauth, qs:qs, json:true}, function (e, r, user) { + console.log(user) + }) + }) +}) +``` + +For [RSA-SHA1 signing](https://tools.ietf.org/html/rfc5849#section-3.4.3), make +the following changes to the OAuth options object: +* Pass `signature_method : 'RSA-SHA1'` +* Instead of `consumer_secret`, specify a `private_key` string in + [PEM format](http://how2ssl.com/articles/working_with_pem_files/) + +For [PLAINTEXT signing](http://oauth.net/core/1.0/#anchor22), make +the following changes to the OAuth options object: +* Pass `signature_method : 'PLAINTEXT'` + +To send OAuth parameters via query params or in a post body as described in The +[Consumer Request Parameters](http://oauth.net/core/1.0/#consumer_req_param) +section of the oauth1 spec: +* Pass `transport_method : 'query'` or `transport_method : 'body'` in the OAuth + options object. +* `transport_method` defaults to `'header'` + +To use [Request Body Hash](https://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html) you can either +* Manually generate the body hash and pass it as a string `body_hash: '...'` +* Automatically generate the body hash by passing `body_hash: true` + +[back to top](#table-of-contents) + + +--- + + +## Proxies + +If you specify a `proxy` option, then the request (and any subsequent +redirects) will be sent via a connection to the proxy server. + +If your endpoint is an `https` url, and you are using a proxy, then +request will send a `CONNECT` request to the proxy server *first*, and +then use the supplied connection to connect to the endpoint. + +That is, first it will make a request like: + +``` +HTTP/1.1 CONNECT endpoint-server.com:80 +Host: proxy-server.com +User-Agent: whatever user agent you specify +``` + +and then the proxy server make a TCP connection to `endpoint-server` +on port `80`, and return a response that looks like: + +``` +HTTP/1.1 200 OK +``` + +At this point, the connection is left open, and the client is +communicating directly with the `endpoint-server.com` machine. + +See [the wikipedia page on HTTP Tunneling](https://en.wikipedia.org/wiki/HTTP_tunnel) +for more information. + +By default, when proxying `http` traffic, request will simply make a +standard proxied `http` request. This is done by making the `url` +section of the initial line of the request a fully qualified url to +the endpoint. + +For example, it will make a single request that looks like: + +``` +HTTP/1.1 GET http://endpoint-server.com/some-url +Host: proxy-server.com +Other-Headers: all go here + +request body or whatever +``` + +Because a pure "http over http" tunnel offers no additional security +or other features, it is generally simpler to go with a +straightforward HTTP proxy in this case. However, if you would like +to force a tunneling proxy, you may set the `tunnel` option to `true`. + +You can also make a standard proxied `http` request by explicitly setting +`tunnel : false`, but **note that this will allow the proxy to see the traffic +to/from the destination server**. + +If you are using a tunneling proxy, you may set the +`proxyHeaderWhiteList` to share certain headers with the proxy. + +You can also set the `proxyHeaderExclusiveList` to share certain +headers only with the proxy and not with destination host. + +By default, this set is: + +``` +accept +accept-charset +accept-encoding +accept-language +accept-ranges +cache-control +content-encoding +content-language +content-length +content-location +content-md5 +content-range +content-type +connection +date +expect +max-forwards +pragma +proxy-authorization +referer +te +transfer-encoding +user-agent +via +``` + +Note that, when using a tunneling proxy, the `proxy-authorization` +header and any headers from custom `proxyHeaderExclusiveList` are +*never* sent to the endpoint server, but only to the proxy server. + + +### Controlling proxy behaviour using environment variables + +The following environment variables are respected by `request`: + + * `HTTP_PROXY` / `http_proxy` + * `HTTPS_PROXY` / `https_proxy` + * `NO_PROXY` / `no_proxy` + +When `HTTP_PROXY` / `http_proxy` are set, they will be used to proxy non-SSL requests that do not have an explicit `proxy` configuration option present. Similarly, `HTTPS_PROXY` / `https_proxy` will be respected for SSL requests that do not have an explicit `proxy` configuration option. It is valid to define a proxy in one of the environment variables, but then override it for a specific request, using the `proxy` configuration option. Furthermore, the `proxy` configuration option can be explicitly set to false / null to opt out of proxying altogether for that request. + +`request` is also aware of the `NO_PROXY`/`no_proxy` environment variables. These variables provide a granular way to opt out of proxying, on a per-host basis. It should contain a comma separated list of hosts to opt out of proxying. It is also possible to opt of proxying when a particular destination port is used. Finally, the variable may be set to `*` to opt out of the implicit proxy configuration of the other environment variables. + +Here's some examples of valid `no_proxy` values: + + * `google.com` - don't proxy HTTP/HTTPS requests to Google. + * `google.com:443` - don't proxy HTTPS requests to Google, but *do* proxy HTTP requests to Google. + * `google.com:443, yahoo.com:80` - don't proxy HTTPS requests to Google, and don't proxy HTTP requests to Yahoo! + * `*` - ignore `https_proxy`/`http_proxy` environment variables altogether. + +[back to top](#table-of-contents) + + +--- + + +## UNIX Domain Sockets + +`request` supports making requests to [UNIX Domain Sockets](https://en.wikipedia.org/wiki/Unix_domain_socket). To make one, use the following URL scheme: + +```js +/* Pattern */ 'http://unix:SOCKET:PATH' +/* Example */ request.get('http://unix:/absolute/path/to/unix.socket:/request/path') +``` + +Note: The `SOCKET` path is assumed to be absolute to the root of the host file system. + +[back to top](#table-of-contents) + + +--- + + +## TLS/SSL Protocol + +TLS/SSL Protocol options, such as `cert`, `key` and `passphrase`, can be +set directly in `options` object, in the `agentOptions` property of the `options` object, or even in `https.globalAgent.options`. Keep in mind that, although `agentOptions` allows for a slightly wider range of configurations, the recommended way is via `options` object directly, as using `agentOptions` or `https.globalAgent.options` would not be applied in the same way in proxied environments (as data travels through a TLS connection instead of an http/https agent). + +```js +var fs = require('fs') + , path = require('path') + , certFile = path.resolve(__dirname, 'ssl/client.crt') + , keyFile = path.resolve(__dirname, 'ssl/client.key') + , caFile = path.resolve(__dirname, 'ssl/ca.cert.pem') + , request = require('request'); + +var options = { + url: 'https://api.some-server.com/', + cert: fs.readFileSync(certFile), + key: fs.readFileSync(keyFile), + passphrase: 'password', + ca: fs.readFileSync(caFile) +}; + +request.get(options); +``` + +### Using `options.agentOptions` + +In the example below, we call an API requires client side SSL certificate +(in PEM format) with passphrase protected private key (in PEM format) and disable the SSLv3 protocol: + +```js +var fs = require('fs') + , path = require('path') + , certFile = path.resolve(__dirname, 'ssl/client.crt') + , keyFile = path.resolve(__dirname, 'ssl/client.key') + , request = require('request'); + +var options = { + url: 'https://api.some-server.com/', + agentOptions: { + cert: fs.readFileSync(certFile), + key: fs.readFileSync(keyFile), + // Or use `pfx` property replacing `cert` and `key` when using private key, certificate and CA certs in PFX or PKCS12 format: + // pfx: fs.readFileSync(pfxFilePath), + passphrase: 'password', + securityOptions: 'SSL_OP_NO_SSLv3' + } +}; + +request.get(options); +``` + +It is able to force using SSLv3 only by specifying `secureProtocol`: + +```js +request.get({ + url: 'https://api.some-server.com/', + agentOptions: { + secureProtocol: 'SSLv3_method' + } +}); +``` + +It is possible to accept other certificates than those signed by generally allowed Certificate Authorities (CAs). +This can be useful, for example, when using self-signed certificates. +To require a different root certificate, you can specify the signing CA by adding the contents of the CA's certificate file to the `agentOptions`. +The certificate the domain presents must be signed by the root certificate specified: + +```js +request.get({ + url: 'https://api.some-server.com/', + agentOptions: { + ca: fs.readFileSync('ca.cert.pem') + } +}); +``` + +[back to top](#table-of-contents) + + +--- + +## Support for HAR 1.2 + +The `options.har` property will override the values: `url`, `method`, `qs`, `headers`, `form`, `formData`, `body`, `json`, as well as construct multipart data and read files from disk when `request.postData.params[].fileName` is present without a matching `value`. + +a validation step will check if the HAR Request format matches the latest spec (v1.2) and will skip parsing if not matching. + +```js + var request = require('request') + request({ + // will be ignored + method: 'GET', + uri: 'http://www.google.com', + + // HTTP Archive Request Object + har: { + url: 'http://www.mockbin.com/har', + method: 'POST', + headers: [ + { + name: 'content-type', + value: 'application/x-www-form-urlencoded' + } + ], + postData: { + mimeType: 'application/x-www-form-urlencoded', + params: [ + { + name: 'foo', + value: 'bar' + }, + { + name: 'hello', + value: 'world' + } + ] + } + } + }) + + // a POST request will be sent to http://www.mockbin.com + // with body an application/x-www-form-urlencoded body: + // foo=bar&hello=world +``` + +[back to top](#table-of-contents) + + +--- + +## request(options, callback) + +The first argument can be either a `url` or an `options` object. The only required option is `uri`; all others are optional. + +- `uri` || `url` - fully qualified uri or a parsed url object from `url.parse()` +- `baseUrl` - fully qualified uri string used as the base url. Most useful with `request.defaults`, for example when you want to do many requests to the same domain. If `baseUrl` is `https://example.com/api/`, then requesting `/end/point?test=true` will fetch `https://example.com/api/end/point?test=true`. When `baseUrl` is given, `uri` must also be a string. +- `method` - http method (default: `"GET"`) +- `headers` - http headers (default: `{}`) + +--- + +- `qs` - object containing querystring values to be appended to the `uri` +- `qsParseOptions` - object containing options to pass to the [qs.parse](https://github.com/hapijs/qs#parsing-objects) method. Alternatively pass options to the [querystring.parse](https://nodejs.org/docs/v0.12.0/api/querystring.html#querystring_querystring_parse_str_sep_eq_options) method using this format `{sep:';', eq:':', options:{}}` +- `qsStringifyOptions` - object containing options to pass to the [qs.stringify](https://github.com/hapijs/qs#stringifying) method. Alternatively pass options to the [querystring.stringify](https://nodejs.org/docs/v0.12.0/api/querystring.html#querystring_querystring_stringify_obj_sep_eq_options) method using this format `{sep:';', eq:':', options:{}}`. For example, to change the way arrays are converted to query strings using the `qs` module pass the `arrayFormat` option with one of `indices|brackets|repeat` +- `useQuerystring` - If true, use `querystring` to stringify and parse + querystrings, otherwise use `qs` (default: `false`). Set this option to + `true` if you need arrays to be serialized as `foo=bar&foo=baz` instead of the + default `foo[0]=bar&foo[1]=baz`. + +--- + +- `body` - entity body for PATCH, POST and PUT requests. Must be a `Buffer`, `String` or `ReadStream`. If `json` is `true`, then `body` must be a JSON-serializable object. +- `form` - when passed an object or a querystring, this sets `body` to a querystring representation of value, and adds `Content-type: application/x-www-form-urlencoded` header. When passed no options, a `FormData` instance is returned (and is piped to request). See "Forms" section above. +- `formData` - Data to pass for a `multipart/form-data` request. See + [Forms](#forms) section above. +- `multipart` - array of objects which contain their own headers and `body` + attributes. Sends a `multipart/related` request. See [Forms](#forms) section + above. + - Alternatively you can pass in an object `{chunked: false, data: []}` where + `chunked` is used to specify whether the request is sent in + [chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding) + In non-chunked requests, data items with body streams are not allowed. +- `preambleCRLF` - append a newline/CRLF before the boundary of your `multipart/form-data` request. +- `postambleCRLF` - append a newline/CRLF at the end of the boundary of your `multipart/form-data` request. +- `json` - sets `body` to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as JSON. +- `jsonReviver` - a [reviver function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) that will be passed to `JSON.parse()` when parsing a JSON response body. +- `jsonReplacer` - a [replacer function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that will be passed to `JSON.stringify()` when stringifying a JSON request body. + +--- + +- `auth` - A hash containing values `user` || `username`, `pass` || `password`, and `sendImmediately` (optional). See documentation above. +- `oauth` - Options for OAuth HMAC-SHA1 signing. See documentation above. +- `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example). +- `aws` - `object` containing AWS signing information. Should have the properties `key`, `secret`, and optionally `session` (note that this only works for services that require session as part of the canonical string). Also requires the property `bucket`, unless you’re specifying your `bucket` as part of the path, or the request doesn’t use a bucket (i.e. GET Services). If you want to use AWS sign version 4 use the parameter `sign_version` with value `4` otherwise the default is version 2. **Note:** you need to `npm install aws4` first. +- `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options. + +--- + +- `followRedirect` - follow HTTP 3xx responses as redirects (default: `true`). This property can also be implemented as function which gets `response` object as a single argument and should return `true` if redirects should continue or `false` otherwise. +- `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects (default: `false`) +- `followOriginalHttpMethod` - by default we redirect to HTTP method GET. you can enable this property to redirect to the original HTTP method (default: `false`) +- `maxRedirects` - the maximum number of redirects to follow (default: `10`) +- `removeRefererHeader` - removes the referer header when a redirect happens (default: `false`). **Note:** if true, referer header set in the initial request is preserved during redirect chain. + +--- + +- `encoding` - Encoding to be used on `setEncoding` of response data. If `null`, the `body` is returned as a `Buffer`. Anything else **(including the default value of `undefined`)** will be passed as the [encoding](http://nodejs.org/api/buffer.html#buffer_buffer) parameter to `toString()` (meaning this is effectively `utf8` by default). (**Note:** if you expect binary data, you should set `encoding: null`.) +- `gzip` - If `true`, add an `Accept-Encoding` header to request compressed content encodings from the server (if not already present) and decode supported content encodings in the response. **Note:** Automatic decoding of the response content is performed on the body data returned through `request` (both through the `request` stream and passed to the callback function) but is not performed on the `response` stream (available from the `response` event) which is the unmodified `http.IncomingMessage` object which may contain compressed data. See example below. +- `jar` - If `true`, remember cookies for future use (or define your custom cookie jar; see examples section) + +--- + +- `agent` - `http(s).Agent` instance to use +- `agentClass` - alternatively specify your agent's class name +- `agentOptions` - and pass its options. **Note:** for HTTPS see [tls API doc for TLS/SSL options](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback) and the [documentation above](#using-optionsagentoptions). +- `forever` - set to `true` to use the [forever-agent](https://github.com/request/forever-agent) **Note:** Defaults to `http(s).Agent({keepAlive:true})` in node 0.12+ +- `pool` - An object describing which agents to use for the request. If this option is omitted the request will use the global agent (as long as your options allow for it). Otherwise, request will search the pool for your custom agent. If no custom agent is found, a new agent will be created and added to the pool. **Note:** `pool` is used only when the `agent` option is not specified. + - A `maxSockets` property can also be provided on the `pool` object to set the max number of sockets for all agents created (ex: `pool: {maxSockets: Infinity}`). + - Note that if you are sending multiple requests in a loop and creating + multiple new `pool` objects, `maxSockets` will not work as intended. To + work around this, either use [`request.defaults`](#requestdefaultsoptions) + with your pool options or create the pool object with the `maxSockets` + property outside of the loop. +- `timeout` - Integer containing the number of milliseconds to wait for a +server to send response headers (and start the response body) before aborting +the request. Note that if the underlying TCP connection cannot be established, +the OS-wide TCP connection timeout will overrule the `timeout` option ([the +default in Linux can be anywhere from 20-120 seconds][linux-timeout]). + +[linux-timeout]: http://www.sekuda.com/overriding_the_default_linux_kernel_20_second_tcp_socket_connect_timeout + +--- + +- `localAddress` - Local interface to bind for network connections. +- `proxy` - An HTTP proxy to be used. Supports proxy Auth with Basic Auth, identical to support for the `url` parameter (by embedding the auth info in the `uri`) +- `strictSSL` - If `true`, requires SSL certificates be valid. **Note:** to use your own certificate authority, you need to specify an agent that was created with that CA as an option. +- `tunnel` - controls the behavior of + [HTTP `CONNECT` tunneling](https://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_tunneling) + as follows: + - `undefined` (default) - `true` if the destination is `https`, `false` otherwise + - `true` - always tunnel to the destination by making a `CONNECT` request to + the proxy + - `false` - request the destination as a `GET` request. +- `proxyHeaderWhiteList` - A whitelist of headers to send to a + tunneling proxy. +- `proxyHeaderExclusiveList` - A whitelist of headers to send + exclusively to a tunneling proxy and not to destination. + +--- + +- `time` - If `true`, the request-response cycle (including all redirects) is timed at millisecond resolution. When set, the following properties are added to the response object: + - `elapsedTime` Duration of the entire request/response in milliseconds (*deprecated*). + - `responseStartTime` Timestamp when the response began (in Unix Epoch milliseconds) (*deprecated*). + - `timingStart` Timestamp of the start of the request (in Unix Epoch milliseconds). + - `timings` Contains event timestamps in millisecond resolution relative to `timingStart`. If there were redirects, the properties reflect the timings of the final request in the redirect chain: + - `socket` Relative timestamp when the [`http`](https://nodejs.org/api/http.html#http_event_socket) module's `socket` event fires. This happens when the socket is assigned to the request. + - `lookup` Relative timestamp when the [`net`](https://nodejs.org/api/net.html#net_event_lookup) module's `lookup` event fires. This happens when the DNS has been resolved. + - `connect`: Relative timestamp when the [`net`](https://nodejs.org/api/net.html#net_event_connect) module's `connect` event fires. This happens when the server acknowledges the TCP connection. + - `response`: Relative timestamp when the [`http`](https://nodejs.org/api/http.html#http_event_response) module's `response` event fires. This happens when the first bytes are received from the server. + - `end`: Relative timestamp when the last bytes of the response are received. + - `timingPhases` Contains the durations of each request phase. If there were redirects, the properties reflect the timings of the final request in the redirect chain: + - `wait`: Duration of socket initialization (`timings.socket`) + - `dns`: Duration of DNS lookup (`timings.lookup` - `timings.socket`) + - `tcp`: Duration of TCP connection (`timings.connect` - `timings.socket`) + - `firstByte`: Duration of HTTP server response (`timings.response` - `timings.connect`) + - `download`: Duration of HTTP download (`timings.end` - `timings.response`) + - `total`: Duration entire HTTP round-trip (`timings.end`) + +- `har` - A [HAR 1.2 Request Object](http://www.softwareishard.com/blog/har-12-spec/#request), will be processed from HAR format into options overwriting matching values *(see the [HAR 1.2 section](#support-for-har-1.2) for details)* +- `callback` - alternatively pass the request's callback in the options object + +The callback argument gets 3 arguments: + +1. An `error` when applicable (usually from [`http.ClientRequest`](http://nodejs.org/api/http.html#http_class_http_clientrequest) object) +2. An [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) object (Response object) +3. The third is the `response` body (`String` or `Buffer`, or JSON object if the `json` option is supplied) + +[back to top](#table-of-contents) + + +--- + +## Convenience methods + +There are also shorthand methods for different HTTP METHODs and some other conveniences. + + +### request.defaults(options) + +This method **returns a wrapper** around the normal request API that defaults +to whatever options you pass to it. + +**Note:** `request.defaults()` **does not** modify the global request API; +instead, it **returns a wrapper** that has your default settings applied to it. + +**Note:** You can call `.defaults()` on the wrapper that is returned from +`request.defaults` to add/override defaults that were previously defaulted. + +For example: +```js +//requests using baseRequest() will set the 'x-token' header +var baseRequest = request.defaults({ + headers: {'x-token': 'my-token'} +}) + +//requests using specialRequest() will include the 'x-token' header set in +//baseRequest and will also include the 'special' header +var specialRequest = baseRequest.defaults({ + headers: {special: 'special value'} +}) +``` + +### request.put + +Same as `request()`, but defaults to `method: "PUT"`. + +```js +request.put(url) +``` + +### request.patch + +Same as `request()`, but defaults to `method: "PATCH"`. + +```js +request.patch(url) +``` + +### request.post + +Same as `request()`, but defaults to `method: "POST"`. + +```js +request.post(url) +``` + +### request.head + +Same as `request()`, but defaults to `method: "HEAD"`. + +```js +request.head(url) +``` + +### request.del / request.delete + +Same as `request()`, but defaults to `method: "DELETE"`. + +```js +request.del(url) +request.delete(url) +``` + +### request.get + +Same as `request()` (for uniformity). + +```js +request.get(url) +``` +### request.cookie + +Function that creates a new cookie. + +```js +request.cookie('key1=value1') +``` +### request.jar() + +Function that creates a new cookie jar. + +```js +request.jar() +``` + +[back to top](#table-of-contents) + + +--- + + +## Debugging + +There are at least three ways to debug the operation of `request`: + +1. Launch the node process like `NODE_DEBUG=request node script.js` + (`lib,request,otherlib` works too). + +2. Set `require('request').debug = true` at any time (this does the same thing + as #1). + +3. Use the [request-debug module](https://github.com/request/request-debug) to + view request and response headers and bodies. + +[back to top](#table-of-contents) + + +--- + +## Timeouts + +Most requests to external servers should have a timeout attached, in case the +server is not responding in a timely manner. Without a timeout, your code may +have a socket open/consume resources for minutes or more. + +There are two main types of timeouts: **connection timeouts** and **read +timeouts**. A connect timeout occurs if the timeout is hit while your client is +attempting to establish a connection to a remote machine (corresponding to the +[connect() call][connect] on the socket). A read timeout occurs any time the +server is too slow to send back a part of the response. + +These two situations have widely different implications for what went wrong +with the request, so it's useful to be able to distinguish them. You can detect +timeout errors by checking `err.code` for an 'ETIMEDOUT' value. Further, you +can detect whether the timeout was a connection timeout by checking if the +`err.connect` property is set to `true`. + +```js +request.get('http://10.255.255.1', {timeout: 1500}, function(err) { + console.log(err.code === 'ETIMEDOUT'); + // Set to `true` if the timeout was a connection timeout, `false` or + // `undefined` otherwise. + console.log(err.connect === true); + process.exit(0); +}); +``` + +[connect]: http://linux.die.net/man/2/connect + +## Examples: + +```js + var request = require('request') + , rand = Math.floor(Math.random()*100000000).toString() + ; + request( + { method: 'PUT' + , uri: 'http://mikeal.iriscouch.com/testjs/' + rand + , multipart: + [ { 'content-type': 'application/json' + , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}}) + } + , { body: 'I am an attachment' } + ] + } + , function (error, response, body) { + if(response.statusCode == 201){ + console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand) + } else { + console.log('error: '+ response.statusCode) + console.log(body) + } + } + ) +``` + +For backwards-compatibility, response compression is not supported by default. +To accept gzip-compressed responses, set the `gzip` option to `true`. Note +that the body data passed through `request` is automatically decompressed +while the response object is unmodified and will contain compressed data if +the server sent a compressed response. + +```js + var request = require('request') + request( + { method: 'GET' + , uri: 'http://www.google.com' + , gzip: true + } + , function (error, response, body) { + // body is the decompressed response body + console.log('server encoded the data as: ' + (response.headers['content-encoding'] || 'identity')) + console.log('the decoded data is: ' + body) + } + ).on('data', function(data) { + // decompressed data as it is received + console.log('decoded chunk: ' + data) + }) + .on('response', function(response) { + // unmodified http.IncomingMessage object + response.on('data', function(data) { + // compressed data as it is received + console.log('received ' + data.length + ' bytes of compressed data') + }) + }) +``` + +Cookies are disabled by default (else, they would be used in subsequent requests). To enable cookies, set `jar` to `true` (either in `defaults` or `options`). + +```js +var request = request.defaults({jar: true}) +request('http://www.google.com', function () { + request('http://images.google.com') +}) +``` + +To use a custom cookie jar (instead of `request`’s global cookie jar), set `jar` to an instance of `request.jar()` (either in `defaults` or `options`) + +```js +var j = request.jar() +var request = request.defaults({jar:j}) +request('http://www.google.com', function () { + request('http://images.google.com') +}) +``` + +OR + +```js +var j = request.jar(); +var cookie = request.cookie('key1=value1'); +var url = 'http://www.google.com'; +j.setCookie(cookie, url); +request({url: url, jar: j}, function () { + request('http://images.google.com') +}) +``` + +To use a custom cookie store (such as a +[`FileCookieStore`](https://github.com/mitsuru/tough-cookie-filestore) +which supports saving to and restoring from JSON files), pass it as a parameter +to `request.jar()`: + +```js +var FileCookieStore = require('tough-cookie-filestore'); +// NOTE - currently the 'cookies.json' file must already exist! +var j = request.jar(new FileCookieStore('cookies.json')); +request = request.defaults({ jar : j }) +request('http://www.google.com', function() { + request('http://images.google.com') +}) +``` + +The cookie store must be a +[`tough-cookie`](https://github.com/SalesforceEng/tough-cookie) +store and it must support synchronous operations; see the +[`CookieStore` API docs](https://github.com/SalesforceEng/tough-cookie#cookiestore-api) +for details. + +To inspect your cookie jar after a request: + +```js +var j = request.jar() +request({url: 'http://www.google.com', jar: j}, function () { + var cookie_string = j.getCookieString(url); // "key1=value1; key2=value2; ..." + var cookies = j.getCookies(url); + // [{key: 'key1', value: 'value1', domain: "www.google.com", ...}, ...] +}) +``` + +[back to top](#table-of-contents) diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/index.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/index.js new file mode 100644 index 0000000000..9ec65ea268 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/index.js @@ -0,0 +1,156 @@ +// Copyright 2010-2012 Mikeal Rogers +// +// 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. + +'use strict' + +var extend = require('extend') + , cookies = require('./lib/cookies') + , helpers = require('./lib/helpers') + +var paramsHaveRequestBody = helpers.paramsHaveRequestBody + + +// organize params for patch, post, put, head, del +function initParams(uri, options, callback) { + if (typeof options === 'function') { + callback = options + } + + var params = {} + if (typeof options === 'object') { + extend(params, options, {uri: uri}) + } else if (typeof uri === 'string') { + extend(params, {uri: uri}) + } else { + extend(params, uri) + } + + params.callback = callback || params.callback + return params +} + +function request (uri, options, callback) { + if (typeof uri === 'undefined') { + throw new Error('undefined is not a valid uri or options object.') + } + + var params = initParams(uri, options, callback) + + if (params.method === 'HEAD' && paramsHaveRequestBody(params)) { + throw new Error('HTTP HEAD requests MUST NOT include a request body.') + } + + return new request.Request(params) +} + +function verbFunc (verb) { + var method = verb.toUpperCase() + return function (uri, options, callback) { + var params = initParams(uri, options, callback) + params.method = method + return request(params, params.callback) + } +} + +// define like this to please codeintel/intellisense IDEs +request.get = verbFunc('get') +request.head = verbFunc('head') +request.post = verbFunc('post') +request.put = verbFunc('put') +request.patch = verbFunc('patch') +request.del = verbFunc('delete') +request['delete'] = verbFunc('delete') + +request.jar = function (store) { + return cookies.jar(store) +} + +request.cookie = function (str) { + return cookies.parse(str) +} + +function wrapRequestMethod (method, options, requester, verb) { + + return function (uri, opts, callback) { + var params = initParams(uri, opts, callback) + + var target = {} + extend(true, target, options, params) + + target.pool = params.pool || options.pool + + if (verb) { + target.method = verb.toUpperCase() + } + + if (typeof requester === 'function') { + method = requester + } + + return method(target, target.callback) + } +} + +request.defaults = function (options, requester) { + var self = this + + options = options || {} + + if (typeof options === 'function') { + requester = options + options = {} + } + + var defaults = wrapRequestMethod(self, options, requester) + + var verbs = ['get', 'head', 'post', 'put', 'patch', 'del', 'delete'] + verbs.forEach(function(verb) { + defaults[verb] = wrapRequestMethod(self[verb], options, requester, verb) + }) + + defaults.cookie = wrapRequestMethod(self.cookie, options, requester) + defaults.jar = self.jar + defaults.defaults = self.defaults + return defaults +} + +request.forever = function (agentOptions, optionsArg) { + var options = {} + if (optionsArg) { + extend(options, optionsArg) + } + if (agentOptions) { + options.agentOptions = agentOptions + } + + options.forever = true + return request.defaults(options) +} + +// Exports + +module.exports = request +request.Request = require('./request') +request.initParams = initParams + +// Backwards compatibility for request.debug +Object.defineProperty(request, 'debug', { + enumerable : true, + get : function() { + return request.Request.debug + }, + set : function(debug) { + request.Request.debug = debug + } +}) diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/auth.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/auth.js new file mode 100644 index 0000000000..559ca57be9 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/auth.js @@ -0,0 +1,168 @@ +'use strict' + +var caseless = require('caseless') + , uuid = require('uuid') + , helpers = require('./helpers') + +var md5 = helpers.md5 + , toBase64 = helpers.toBase64 + + +function Auth (request) { + // define all public properties here + this.request = request + this.hasAuth = false + this.sentAuth = false + this.bearerToken = null + this.user = null + this.pass = null +} + +Auth.prototype.basic = function (user, pass, sendImmediately) { + var self = this + if (typeof user !== 'string' || (pass !== undefined && typeof pass !== 'string')) { + self.request.emit('error', new Error('auth() received invalid user or password')) + } + self.user = user + self.pass = pass + self.hasAuth = true + var header = user + ':' + (pass || '') + if (sendImmediately || typeof sendImmediately === 'undefined') { + var authHeader = 'Basic ' + toBase64(header) + self.sentAuth = true + return authHeader + } +} + +Auth.prototype.bearer = function (bearer, sendImmediately) { + var self = this + self.bearerToken = bearer + self.hasAuth = true + if (sendImmediately || typeof sendImmediately === 'undefined') { + if (typeof bearer === 'function') { + bearer = bearer() + } + var authHeader = 'Bearer ' + (bearer || '') + self.sentAuth = true + return authHeader + } +} + +Auth.prototype.digest = function (method, path, authHeader) { + // TODO: More complete implementation of RFC 2617. + // - handle challenge.domain + // - support qop="auth-int" only + // - handle Authentication-Info (not necessarily?) + // - check challenge.stale (not necessarily?) + // - increase nc (not necessarily?) + // For reference: + // http://tools.ietf.org/html/rfc2617#section-3 + // https://github.com/bagder/curl/blob/master/lib/http_digest.c + + var self = this + + var challenge = {} + var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi + for (;;) { + var match = re.exec(authHeader) + if (!match) { + break + } + challenge[match[1]] = match[2] || match[3] + } + + /** + * RFC 2617: handle both MD5 and MD5-sess algorithms. + * + * If the algorithm directive's value is "MD5" or unspecified, then HA1 is + * HA1=MD5(username:realm:password) + * If the algorithm directive's value is "MD5-sess", then HA1 is + * HA1=MD5(MD5(username:realm:password):nonce:cnonce) + */ + var ha1Compute = function (algorithm, user, realm, pass, nonce, cnonce) { + var ha1 = md5(user + ':' + realm + ':' + pass) + if (algorithm && algorithm.toLowerCase() === 'md5-sess') { + return md5(ha1 + ':' + nonce + ':' + cnonce) + } else { + return ha1 + } + } + + var qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth' + var nc = qop && '00000001' + var cnonce = qop && uuid().replace(/-/g, '') + var ha1 = ha1Compute(challenge.algorithm, self.user, challenge.realm, self.pass, challenge.nonce, cnonce) + var ha2 = md5(method + ':' + path) + var digestResponse = qop + ? md5(ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) + : md5(ha1 + ':' + challenge.nonce + ':' + ha2) + var authValues = { + username: self.user, + realm: challenge.realm, + nonce: challenge.nonce, + uri: path, + qop: qop, + response: digestResponse, + nc: nc, + cnonce: cnonce, + algorithm: challenge.algorithm, + opaque: challenge.opaque + } + + authHeader = [] + for (var k in authValues) { + if (authValues[k]) { + if (k === 'qop' || k === 'nc' || k === 'algorithm') { + authHeader.push(k + '=' + authValues[k]) + } else { + authHeader.push(k + '="' + authValues[k] + '"') + } + } + } + authHeader = 'Digest ' + authHeader.join(', ') + self.sentAuth = true + return authHeader +} + +Auth.prototype.onRequest = function (user, pass, sendImmediately, bearer) { + var self = this + , request = self.request + + var authHeader + if (bearer === undefined && user === undefined) { + self.request.emit('error', new Error('no auth mechanism defined')) + } else if (bearer !== undefined) { + authHeader = self.bearer(bearer, sendImmediately) + } else { + authHeader = self.basic(user, pass, sendImmediately) + } + if (authHeader) { + request.setHeader('authorization', authHeader) + } +} + +Auth.prototype.onResponse = function (response) { + var self = this + , request = self.request + + if (!self.hasAuth || self.sentAuth) { return null } + + var c = caseless(response.headers) + + var authHeader = c.get('www-authenticate') + var authVerb = authHeader && authHeader.split(' ')[0].toLowerCase() + request.debug('reauth', authVerb) + + switch (authVerb) { + case 'basic': + return self.basic(self.user, self.pass, true) + + case 'bearer': + return self.bearer(self.bearerToken, true) + + case 'digest': + return self.digest(request.method, request.path, authHeader) + } +} + +exports.Auth = Auth diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/cookies.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/cookies.js new file mode 100644 index 0000000000..412c07d63b --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/cookies.js @@ -0,0 +1,39 @@ +'use strict' + +var tough = require('tough-cookie') + +var Cookie = tough.Cookie + , CookieJar = tough.CookieJar + + +exports.parse = function(str) { + if (str && str.uri) { + str = str.uri + } + if (typeof str !== 'string') { + throw new Error('The cookie function only accepts STRING as param') + } + return Cookie.parse(str, {loose: true}) +} + +// Adapt the sometimes-Async api of tough.CookieJar to our requirements +function RequestJar(store) { + var self = this + self._jar = new CookieJar(store, {looseMode: true}) +} +RequestJar.prototype.setCookie = function(cookieOrStr, uri, options) { + var self = this + return self._jar.setCookieSync(cookieOrStr, uri, options || {}) +} +RequestJar.prototype.getCookieString = function(uri) { + var self = this + return self._jar.getCookieStringSync(uri) +} +RequestJar.prototype.getCookies = function(uri) { + var self = this + return self._jar.getCookiesSync(uri) +} + +exports.jar = function(store) { + return new RequestJar(store) +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/getProxyFromURI.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/getProxyFromURI.js new file mode 100644 index 0000000000..c2013a6e12 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/getProxyFromURI.js @@ -0,0 +1,79 @@ +'use strict' + +function formatHostname(hostname) { + // canonicalize the hostname, so that 'oogle.com' won't match 'google.com' + return hostname.replace(/^\.*/, '.').toLowerCase() +} + +function parseNoProxyZone(zone) { + zone = zone.trim().toLowerCase() + + var zoneParts = zone.split(':', 2) + , zoneHost = formatHostname(zoneParts[0]) + , zonePort = zoneParts[1] + , hasPort = zone.indexOf(':') > -1 + + return {hostname: zoneHost, port: zonePort, hasPort: hasPort} +} + +function uriInNoProxy(uri, noProxy) { + var port = uri.port || (uri.protocol === 'https:' ? '443' : '80') + , hostname = formatHostname(uri.hostname) + , noProxyList = noProxy.split(',') + + // iterate through the noProxyList until it finds a match. + return noProxyList.map(parseNoProxyZone).some(function(noProxyZone) { + var isMatchedAt = hostname.indexOf(noProxyZone.hostname) + , hostnameMatched = ( + isMatchedAt > -1 && + (isMatchedAt === hostname.length - noProxyZone.hostname.length) + ) + + if (noProxyZone.hasPort) { + return (port === noProxyZone.port) && hostnameMatched + } + + return hostnameMatched + }) +} + +function getProxyFromURI(uri) { + // Decide the proper request proxy to use based on the request URI object and the + // environmental variables (NO_PROXY, HTTP_PROXY, etc.) + // respect NO_PROXY environment variables (see: http://lynx.isc.org/current/breakout/lynx_help/keystrokes/environments.html) + + var noProxy = process.env.NO_PROXY || process.env.no_proxy || '' + + // if the noProxy is a wildcard then return null + + if (noProxy === '*') { + return null + } + + // if the noProxy is not empty and the uri is found return null + + if (noProxy !== '' && uriInNoProxy(uri, noProxy)) { + return null + } + + // Check for HTTP or HTTPS Proxy in environment Else default to null + + if (uri.protocol === 'http:') { + return process.env.HTTP_PROXY || + process.env.http_proxy || null + } + + if (uri.protocol === 'https:') { + return process.env.HTTPS_PROXY || + process.env.https_proxy || + process.env.HTTP_PROXY || + process.env.http_proxy || null + } + + // if none of that works, return null + // (What uri protocol are you using then?) + + return null +} + +module.exports = getProxyFromURI diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/har.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/har.js new file mode 100644 index 0000000000..3059574878 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/har.js @@ -0,0 +1,215 @@ +'use strict' + +var fs = require('fs') +var qs = require('querystring') +var validate = require('har-validator') +var extend = require('extend') + +function Har (request) { + this.request = request +} + +Har.prototype.reducer = function (obj, pair) { + // new property ? + if (obj[pair.name] === undefined) { + obj[pair.name] = pair.value + return obj + } + + // existing? convert to array + var arr = [ + obj[pair.name], + pair.value + ] + + obj[pair.name] = arr + + return obj +} + +Har.prototype.prep = function (data) { + // construct utility properties + data.queryObj = {} + data.headersObj = {} + data.postData.jsonObj = false + data.postData.paramsObj = false + + // construct query objects + if (data.queryString && data.queryString.length) { + data.queryObj = data.queryString.reduce(this.reducer, {}) + } + + // construct headers objects + if (data.headers && data.headers.length) { + // loweCase header keys + data.headersObj = data.headers.reduceRight(function (headers, header) { + headers[header.name] = header.value + return headers + }, {}) + } + + // construct Cookie header + if (data.cookies && data.cookies.length) { + var cookies = data.cookies.map(function (cookie) { + return cookie.name + '=' + cookie.value + }) + + if (cookies.length) { + data.headersObj.cookie = cookies.join('; ') + } + } + + // prep body + function some (arr) { + return arr.some(function (type) { + return data.postData.mimeType.indexOf(type) === 0 + }) + } + + if (some([ + 'multipart/mixed', + 'multipart/related', + 'multipart/form-data', + 'multipart/alternative'])) { + + // reset values + data.postData.mimeType = 'multipart/form-data' + } + + else if (some([ + 'application/x-www-form-urlencoded'])) { + + if (!data.postData.params) { + data.postData.text = '' + } else { + data.postData.paramsObj = data.postData.params.reduce(this.reducer, {}) + + // always overwrite + data.postData.text = qs.stringify(data.postData.paramsObj) + } + } + + else if (some([ + 'text/json', + 'text/x-json', + 'application/json', + 'application/x-json'])) { + + data.postData.mimeType = 'application/json' + + if (data.postData.text) { + try { + data.postData.jsonObj = JSON.parse(data.postData.text) + } catch (e) { + this.request.debug(e) + + // force back to text/plain + data.postData.mimeType = 'text/plain' + } + } + } + + return data +} + +Har.prototype.options = function (options) { + // skip if no har property defined + if (!options.har) { + return options + } + + var har = {} + extend(har, options.har) + + // only process the first entry + if (har.log && har.log.entries) { + har = har.log.entries[0] + } + + // add optional properties to make validation successful + har.url = har.url || options.url || options.uri || options.baseUrl || '/' + har.httpVersion = har.httpVersion || 'HTTP/1.1' + har.queryString = har.queryString || [] + har.headers = har.headers || [] + har.cookies = har.cookies || [] + har.postData = har.postData || {} + har.postData.mimeType = har.postData.mimeType || 'application/octet-stream' + + har.bodySize = 0 + har.headersSize = 0 + har.postData.size = 0 + + if (!validate.request(har)) { + return options + } + + // clean up and get some utility properties + var req = this.prep(har) + + // construct new options + if (req.url) { + options.url = req.url + } + + if (req.method) { + options.method = req.method + } + + if (Object.keys(req.queryObj).length) { + options.qs = req.queryObj + } + + if (Object.keys(req.headersObj).length) { + options.headers = req.headersObj + } + + function test (type) { + return req.postData.mimeType.indexOf(type) === 0 + } + if (test('application/x-www-form-urlencoded')) { + options.form = req.postData.paramsObj + } + else if (test('application/json')) { + if (req.postData.jsonObj) { + options.body = req.postData.jsonObj + options.json = true + } + } + else if (test('multipart/form-data')) { + options.formData = {} + + req.postData.params.forEach(function (param) { + var attachment = {} + + if (!param.fileName && !param.fileName && !param.contentType) { + options.formData[param.name] = param.value + return + } + + // attempt to read from disk! + if (param.fileName && !param.value) { + attachment.value = fs.createReadStream(param.fileName) + } else if (param.value) { + attachment.value = param.value + } + + if (param.fileName) { + attachment.options = { + filename: param.fileName, + contentType: param.contentType ? param.contentType : null + } + } + + options.formData[param.name] = attachment + }) + } + else { + if (req.postData.text) { + options.body = req.postData.text + } + } + + return options +} + +exports.Har = Har diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/helpers.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/helpers.js new file mode 100644 index 0000000000..05c77a0bdd --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/helpers.js @@ -0,0 +1,66 @@ +'use strict' + +var jsonSafeStringify = require('json-stringify-safe') + , crypto = require('crypto') + , Buffer = require('safe-buffer').Buffer + +var defer = typeof setImmediate === 'undefined' + ? process.nextTick + : setImmediate + +function paramsHaveRequestBody(params) { + return ( + params.body || + params.requestBodyStream || + (params.json && typeof params.json !== 'boolean') || + params.multipart + ) +} + +function safeStringify (obj, replacer) { + var ret + try { + ret = JSON.stringify(obj, replacer) + } catch (e) { + ret = jsonSafeStringify(obj, replacer) + } + return ret +} + +function md5 (str) { + return crypto.createHash('md5').update(str).digest('hex') +} + +function isReadStream (rs) { + return rs.readable && rs.path && rs.mode +} + +function toBase64 (str) { + return Buffer.from(str || '', 'utf8').toString('base64') +} + +function copy (obj) { + var o = {} + Object.keys(obj).forEach(function (i) { + o[i] = obj[i] + }) + return o +} + +function version () { + var numbers = process.version.replace('v', '').split('.') + return { + major: parseInt(numbers[0], 10), + minor: parseInt(numbers[1], 10), + patch: parseInt(numbers[2], 10) + } +} + +exports.paramsHaveRequestBody = paramsHaveRequestBody +exports.safeStringify = safeStringify +exports.md5 = md5 +exports.isReadStream = isReadStream +exports.toBase64 = toBase64 +exports.copy = copy +exports.version = version +exports.defer = defer diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/multipart.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/multipart.js new file mode 100644 index 0000000000..fc7b50276e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/multipart.js @@ -0,0 +1,113 @@ +'use strict' + +var uuid = require('uuid') + , CombinedStream = require('combined-stream') + , isstream = require('isstream') + , Buffer = require('safe-buffer').Buffer + + +function Multipart (request) { + this.request = request + this.boundary = uuid() + this.chunked = false + this.body = null +} + +Multipart.prototype.isChunked = function (options) { + var self = this + , chunked = false + , parts = options.data || options + + if (!parts.forEach) { + self.request.emit('error', new Error('Argument error, options.multipart.')) + } + + if (options.chunked !== undefined) { + chunked = options.chunked + } + + if (self.request.getHeader('transfer-encoding') === 'chunked') { + chunked = true + } + + if (!chunked) { + parts.forEach(function (part) { + if (typeof part.body === 'undefined') { + self.request.emit('error', new Error('Body attribute missing in multipart.')) + } + if (isstream(part.body)) { + chunked = true + } + }) + } + + return chunked +} + +Multipart.prototype.setHeaders = function (chunked) { + var self = this + + if (chunked && !self.request.hasHeader('transfer-encoding')) { + self.request.setHeader('transfer-encoding', 'chunked') + } + + var header = self.request.getHeader('content-type') + + if (!header || header.indexOf('multipart') === -1) { + self.request.setHeader('content-type', 'multipart/related; boundary=' + self.boundary) + } else { + if (header.indexOf('boundary') !== -1) { + self.boundary = header.replace(/.*boundary=([^\s;]+).*/, '$1') + } else { + self.request.setHeader('content-type', header + '; boundary=' + self.boundary) + } + } +} + +Multipart.prototype.build = function (parts, chunked) { + var self = this + var body = chunked ? new CombinedStream() : [] + + function add (part) { + if (typeof part === 'number') { + part = part.toString() + } + return chunked ? body.append(part) : body.push(Buffer.from(part)) + } + + if (self.request.preambleCRLF) { + add('\r\n') + } + + parts.forEach(function (part) { + var preamble = '--' + self.boundary + '\r\n' + Object.keys(part).forEach(function (key) { + if (key === 'body') { return } + preamble += key + ': ' + part[key] + '\r\n' + }) + preamble += '\r\n' + add(preamble) + add(part.body) + add('\r\n') + }) + add('--' + self.boundary + '--') + + if (self.request.postambleCRLF) { + add('\r\n') + } + + return body +} + +Multipart.prototype.onRequest = function (options) { + var self = this + + var chunked = self.isChunked(options) + , parts = options.data || options + + self.setHeaders(chunked) + self.chunked = chunked + self.body = self.build(parts, chunked) +} + +exports.Multipart = Multipart diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/oauth.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/oauth.js new file mode 100644 index 0000000000..13b693773e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/oauth.js @@ -0,0 +1,148 @@ +'use strict' + +var url = require('url') + , qs = require('qs') + , caseless = require('caseless') + , uuid = require('uuid') + , oauth = require('oauth-sign') + , crypto = require('crypto') + , Buffer = require('safe-buffer').Buffer + + +function OAuth (request) { + this.request = request + this.params = null +} + +OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) { + var oa = {} + for (var i in _oauth) { + oa['oauth_' + i] = _oauth[i] + } + if (!oa.oauth_version) { + oa.oauth_version = '1.0' + } + if (!oa.oauth_timestamp) { + oa.oauth_timestamp = Math.floor( Date.now() / 1000 ).toString() + } + if (!oa.oauth_nonce) { + oa.oauth_nonce = uuid().replace(/-/g, '') + } + if (!oa.oauth_signature_method) { + oa.oauth_signature_method = 'HMAC-SHA1' + } + + var consumer_secret_or_private_key = oa.oauth_consumer_secret || oa.oauth_private_key + delete oa.oauth_consumer_secret + delete oa.oauth_private_key + + var token_secret = oa.oauth_token_secret + delete oa.oauth_token_secret + + var realm = oa.oauth_realm + delete oa.oauth_realm + delete oa.oauth_transport_method + + var baseurl = uri.protocol + '//' + uri.host + uri.pathname + var params = qsLib.parse([].concat(query, form, qsLib.stringify(oa)).join('&')) + + oa.oauth_signature = oauth.sign( + oa.oauth_signature_method, + method, + baseurl, + params, + consumer_secret_or_private_key, + token_secret) + + if (realm) { + oa.realm = realm + } + + return oa +} + +OAuth.prototype.buildBodyHash = function(_oauth, body) { + if (['HMAC-SHA1', 'RSA-SHA1'].indexOf(_oauth.signature_method || 'HMAC-SHA1') < 0) { + this.request.emit('error', new Error('oauth: ' + _oauth.signature_method + + ' signature_method not supported with body_hash signing.')) + } + + var shasum = crypto.createHash('sha1') + shasum.update(body || '') + var sha1 = shasum.digest('hex') + + return Buffer.from(sha1).toString('base64') +} + +OAuth.prototype.concatParams = function (oa, sep, wrap) { + wrap = wrap || '' + + var params = Object.keys(oa).filter(function (i) { + return i !== 'realm' && i !== 'oauth_signature' + }).sort() + + if (oa.realm) { + params.splice(0, 0, 'realm') + } + params.push('oauth_signature') + + return params.map(function (i) { + return i + '=' + wrap + oauth.rfc3986(oa[i]) + wrap + }).join(sep) +} + +OAuth.prototype.onRequest = function (_oauth) { + var self = this + self.params = _oauth + + var uri = self.request.uri || {} + , method = self.request.method || '' + , headers = caseless(self.request.headers) + , body = self.request.body || '' + , qsLib = self.request.qsLib || qs + + var form + , query + , contentType = headers.get('content-type') || '' + , formContentType = 'application/x-www-form-urlencoded' + , transport = _oauth.transport_method || 'header' + + if (contentType.slice(0, formContentType.length) === formContentType) { + contentType = formContentType + form = body + } + if (uri.query) { + query = uri.query + } + if (transport === 'body' && (method !== 'POST' || contentType !== formContentType)) { + self.request.emit('error', new Error('oauth: transport_method of body requires POST ' + + 'and content-type ' + formContentType)) + } + + if (!form && typeof _oauth.body_hash === 'boolean') { + _oauth.body_hash = self.buildBodyHash(_oauth, self.request.body.toString()) + } + + var oa = self.buildParams(_oauth, uri, method, query, form, qsLib) + + switch (transport) { + case 'header': + self.request.setHeader('Authorization', 'OAuth ' + self.concatParams(oa, ',', '"')) + break + + case 'query': + var href = self.request.uri.href += (query ? '&' : '?') + self.concatParams(oa, '&') + self.request.uri = url.parse(href) + self.request.path = self.request.uri.path + break + + case 'body': + self.request.body = (form ? form + '&' : '') + self.concatParams(oa, '&') + break + + default: + self.request.emit('error', new Error('oauth: transport_method invalid')) + } +} + +exports.OAuth = OAuth diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/querystring.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/querystring.js new file mode 100644 index 0000000000..baf5e8021f --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/querystring.js @@ -0,0 +1,51 @@ +'use strict' + +var qs = require('qs') + , querystring = require('querystring') + + +function Querystring (request) { + this.request = request + this.lib = null + this.useQuerystring = null + this.parseOptions = null + this.stringifyOptions = null +} + +Querystring.prototype.init = function (options) { + if (this.lib) {return} + + this.useQuerystring = options.useQuerystring + this.lib = (this.useQuerystring ? querystring : qs) + + this.parseOptions = options.qsParseOptions || {} + this.stringifyOptions = options.qsStringifyOptions || {} +} + +Querystring.prototype.stringify = function (obj) { + return (this.useQuerystring) + ? this.rfc3986(this.lib.stringify(obj, + this.stringifyOptions.sep || null, + this.stringifyOptions.eq || null, + this.stringifyOptions)) + : this.lib.stringify(obj, this.stringifyOptions) +} + +Querystring.prototype.parse = function (str) { + return (this.useQuerystring) + ? this.lib.parse(str, + this.parseOptions.sep || null, + this.parseOptions.eq || null, + this.parseOptions) + : this.lib.parse(str, this.parseOptions) +} + +Querystring.prototype.rfc3986 = function (str) { + return str.replace(/[!'()*]/g, function (c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +Querystring.prototype.unescape = querystring.unescape + +exports.Querystring = Querystring diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/redirect.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/redirect.js new file mode 100644 index 0000000000..f8604491f3 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/redirect.js @@ -0,0 +1,157 @@ +'use strict' + +var url = require('url') +var isUrl = /^https?:/ + +function Redirect (request) { + this.request = request + this.followRedirect = true + this.followRedirects = true + this.followAllRedirects = false + this.followOriginalHttpMethod = false + this.allowRedirect = function () {return true} + this.maxRedirects = 10 + this.redirects = [] + this.redirectsFollowed = 0 + this.removeRefererHeader = false +} + +Redirect.prototype.onRequest = function (options) { + var self = this + + if (options.maxRedirects !== undefined) { + self.maxRedirects = options.maxRedirects + } + if (typeof options.followRedirect === 'function') { + self.allowRedirect = options.followRedirect + } + if (options.followRedirect !== undefined) { + self.followRedirects = !!options.followRedirect + } + if (options.followAllRedirects !== undefined) { + self.followAllRedirects = options.followAllRedirects + } + if (self.followRedirects || self.followAllRedirects) { + self.redirects = self.redirects || [] + } + if (options.removeRefererHeader !== undefined) { + self.removeRefererHeader = options.removeRefererHeader + } + if (options.followOriginalHttpMethod !== undefined) { + self.followOriginalHttpMethod = options.followOriginalHttpMethod + } +} + +Redirect.prototype.redirectTo = function (response) { + var self = this + , request = self.request + + var redirectTo = null + if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) { + var location = response.caseless.get('location') + request.debug('redirect', location) + + if (self.followAllRedirects) { + redirectTo = location + } else if (self.followRedirects) { + switch (request.method) { + case 'PATCH': + case 'PUT': + case 'POST': + case 'DELETE': + // Do not follow redirects + break + default: + redirectTo = location + break + } + } + } else if (response.statusCode === 401) { + var authHeader = request._auth.onResponse(response) + if (authHeader) { + request.setHeader('authorization', authHeader) + redirectTo = request.uri + } + } + return redirectTo +} + +Redirect.prototype.onResponse = function (response) { + var self = this + , request = self.request + + var redirectTo = self.redirectTo(response) + if (!redirectTo || !self.allowRedirect.call(request, response)) { + return false + } + + request.debug('redirect to', redirectTo) + + // ignore any potential response body. it cannot possibly be useful + // to us at this point. + // response.resume should be defined, but check anyway before calling. Workaround for browserify. + if (response.resume) { + response.resume() + } + + if (self.redirectsFollowed >= self.maxRedirects) { + request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href)) + return false + } + self.redirectsFollowed += 1 + + if (!isUrl.test(redirectTo)) { + redirectTo = url.resolve(request.uri.href, redirectTo) + } + + var uriPrev = request.uri + request.uri = url.parse(redirectTo) + + // handle the case where we change protocol from https to http or vice versa + if (request.uri.protocol !== uriPrev.protocol) { + delete request.agent + } + + self.redirects.push( + { statusCode : response.statusCode + , redirectUri: redirectTo + } + ) + if (self.followAllRedirects && request.method !== 'HEAD' + && response.statusCode !== 401 && response.statusCode !== 307) { + request.method = self.followOriginalHttpMethod ? request.method : 'GET' + } + // request.method = 'GET' // Force all redirects to use GET || commented out fixes #215 + delete request.src + delete request.req + delete request._started + if (response.statusCode !== 401 && response.statusCode !== 307) { + // Remove parameters from the previous response, unless this is the second request + // for a server that requires digest authentication. + delete request.body + delete request._form + if (request.headers) { + request.removeHeader('host') + request.removeHeader('content-type') + request.removeHeader('content-length') + if (request.uri.hostname !== request.originalHost.split(':')[0]) { + // Remove authorization if changing hostnames (but not if just + // changing ports or protocols). This matches the behavior of curl: + // https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710 + request.removeHeader('authorization') + } + } + } + + if (!self.removeRefererHeader) { + request.setHeader('referer', uriPrev.href) + } + + request.emit('redirect') + + request.init() + + return true +} + +exports.Redirect = Redirect diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/tunnel.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/tunnel.js new file mode 100644 index 0000000000..bf96a8fec5 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/lib/tunnel.js @@ -0,0 +1,176 @@ +'use strict' + +var url = require('url') + , tunnel = require('tunnel-agent') + +var defaultProxyHeaderWhiteList = [ + 'accept', + 'accept-charset', + 'accept-encoding', + 'accept-language', + 'accept-ranges', + 'cache-control', + 'content-encoding', + 'content-language', + 'content-location', + 'content-md5', + 'content-range', + 'content-type', + 'connection', + 'date', + 'expect', + 'max-forwards', + 'pragma', + 'referer', + 'te', + 'user-agent', + 'via' +] + +var defaultProxyHeaderExclusiveList = [ + 'proxy-authorization' +] + +function constructProxyHost(uriObject) { + var port = uriObject.port + , protocol = uriObject.protocol + , proxyHost = uriObject.hostname + ':' + + if (port) { + proxyHost += port + } else if (protocol === 'https:') { + proxyHost += '443' + } else { + proxyHost += '80' + } + + return proxyHost +} + +function constructProxyHeaderWhiteList(headers, proxyHeaderWhiteList) { + var whiteList = proxyHeaderWhiteList + .reduce(function (set, header) { + set[header.toLowerCase()] = true + return set + }, {}) + + return Object.keys(headers) + .filter(function (header) { + return whiteList[header.toLowerCase()] + }) + .reduce(function (set, header) { + set[header] = headers[header] + return set + }, {}) +} + +function constructTunnelOptions (request, proxyHeaders) { + var proxy = request.proxy + + var tunnelOptions = { + proxy : { + host : proxy.hostname, + port : +proxy.port, + proxyAuth : proxy.auth, + headers : proxyHeaders + }, + headers : request.headers, + ca : request.ca, + cert : request.cert, + key : request.key, + passphrase : request.passphrase, + pfx : request.pfx, + ciphers : request.ciphers, + rejectUnauthorized : request.rejectUnauthorized, + secureOptions : request.secureOptions, + secureProtocol : request.secureProtocol + } + + return tunnelOptions +} + +function constructTunnelFnName(uri, proxy) { + var uriProtocol = (uri.protocol === 'https:' ? 'https' : 'http') + var proxyProtocol = (proxy.protocol === 'https:' ? 'Https' : 'Http') + return [uriProtocol, proxyProtocol].join('Over') +} + +function getTunnelFn(request) { + var uri = request.uri + var proxy = request.proxy + var tunnelFnName = constructTunnelFnName(uri, proxy) + return tunnel[tunnelFnName] +} + + +function Tunnel (request) { + this.request = request + this.proxyHeaderWhiteList = defaultProxyHeaderWhiteList + this.proxyHeaderExclusiveList = [] + if (typeof request.tunnel !== 'undefined') { + this.tunnelOverride = request.tunnel + } +} + +Tunnel.prototype.isEnabled = function () { + var self = this + , request = self.request + // Tunnel HTTPS by default. Allow the user to override this setting. + + // If self.tunnelOverride is set (the user specified a value), use it. + if (typeof self.tunnelOverride !== 'undefined') { + return self.tunnelOverride + } + + // If the destination is HTTPS, tunnel. + if (request.uri.protocol === 'https:') { + return true + } + + // Otherwise, do not use tunnel. + return false +} + +Tunnel.prototype.setup = function (options) { + var self = this + , request = self.request + + options = options || {} + + if (typeof request.proxy === 'string') { + request.proxy = url.parse(request.proxy) + } + + if (!request.proxy || !request.tunnel) { + return false + } + + // Setup Proxy Header Exclusive List and White List + if (options.proxyHeaderWhiteList) { + self.proxyHeaderWhiteList = options.proxyHeaderWhiteList + } + if (options.proxyHeaderExclusiveList) { + self.proxyHeaderExclusiveList = options.proxyHeaderExclusiveList + } + + var proxyHeaderExclusiveList = self.proxyHeaderExclusiveList.concat(defaultProxyHeaderExclusiveList) + var proxyHeaderWhiteList = self.proxyHeaderWhiteList.concat(proxyHeaderExclusiveList) + + // Setup Proxy Headers and Proxy Headers Host + // Only send the Proxy White Listed Header names + var proxyHeaders = constructProxyHeaderWhiteList(request.headers, proxyHeaderWhiteList) + proxyHeaders.host = constructProxyHost(request.uri) + + proxyHeaderExclusiveList.forEach(request.removeHeader, request) + + // Set Agent from Tunnel Data + var tunnelFn = getTunnelFn(request) + var tunnelOptions = constructTunnelOptions(request, proxyHeaders) + request.agent = tunnelFn(tunnelOptions) + + return true +} + +Tunnel.defaultProxyHeaderWhiteList = defaultProxyHeaderWhiteList +Tunnel.defaultProxyHeaderExclusiveList = defaultProxyHeaderExclusiveList +exports.Tunnel = Tunnel diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/request/package.json new file mode 100644 index 0000000000..765cbd0ae4 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/package.json @@ -0,0 +1,166 @@ +{ + "_args": [ + [ + { + "raw": "request", + "scope": null, + "escapedName": "request", + "name": "request", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules" + ] + ], + "_from": "request@latest", + "_id": "request@2.81.0", + "_inCache": true, + "_location": "/request", + "_nodeVersion": "7.2.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/request-2.81.0.tgz_1489075005134_0.036041518207639456" + }, + "_npmUser": { + "name": "simov", + "email": "simeonvelichkov@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "request", + "scope": null, + "escapedName": "request", + "name": "request", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "_shasum": "c6928946a0e06c5f8d6f8a9333469ffda46298a0", + "_shrinkwrap": null, + "_spec": "request", + "_where": "/Library/Application Support/Adobe/CEP/extensions/aeft/node_modules", + "author": { + "name": "Mikeal Rogers", + "email": "mikeal.rogers@gmail.com" + }, + "bugs": { + "url": "http://github.com/request/request/issues" + }, + "dependencies": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + }, + "description": "Simplified HTTP request client.", + "devDependencies": { + "bluebird": "^3.2.1", + "browserify": "^13.0.1", + "browserify-istanbul": "^2.0.0", + "buffer-equal": "^1.0.0", + "codecov": "^1.0.1", + "coveralls": "^2.11.4", + "eslint": "^2.5.3", + "function-bind": "^1.0.2", + "istanbul": "^0.4.0", + "karma": "^1.1.1", + "karma-browserify": "^5.0.1", + "karma-cli": "^1.0.0", + "karma-coverage": "^1.0.0", + "karma-phantomjs-launcher": "^1.0.0", + "karma-tap": "^3.0.1", + "phantomjs-prebuilt": "^2.1.3", + "rimraf": "^2.2.8", + "server-destroy": "^1.0.1", + "tape": "^4.6.0", + "taper": "^0.5.0" + }, + "directories": {}, + "dist": { + "shasum": "c6928946a0e06c5f8d6f8a9333469ffda46298a0", + "tarball": "https://registry.npmjs.org/request/-/request-2.81.0.tgz" + }, + "engines": { + "node": ">= 4" + }, + "files": [ + "lib/", + "index.js", + "request.js" + ], + "gitHead": "a0cdc704c19e63e6f1740e173bb003c51eef524c", + "greenkeeper": { + "ignore": [ + "eslint", + "hawk", + "har-validator" + ] + }, + "homepage": "https://github.com/request/request#readme", + "keywords": [ + "http", + "simple", + "util", + "utility" + ], + "license": "Apache-2.0", + "main": "index.js", + "maintainers": [ + { + "name": "mikeal", + "email": "mikeal.rogers@gmail.com" + }, + { + "name": "nylen", + "email": "jnylen@gmail.com" + }, + { + "name": "fredkschott", + "email": "fkschott@gmail.com" + }, + { + "name": "simov", + "email": "simeonvelichkov@gmail.com" + } + ], + "name": "request", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/request/request.git" + }, + "scripts": { + "lint": "eslint lib/ *.js tests/ && echo Lint passed.", + "test": "npm run lint && npm run test-ci && npm run test-browser", + "test-browser": "node tests/browser/start.js", + "test-ci": "taper tests/test-*.js", + "test-cov": "istanbul cover tape tests/test-*.js" + }, + "version": "2.81.0" +} diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/request/request.js b/pype/premiere/extensions/com.pype.avalon/node_modules/request/request.js new file mode 100644 index 0000000000..467524ba4e --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/request/request.js @@ -0,0 +1,1565 @@ +'use strict' + +var http = require('http') + , https = require('https') + , url = require('url') + , util = require('util') + , stream = require('stream') + , zlib = require('zlib') + , hawk = require('hawk') + , aws2 = require('aws-sign2') + , aws4 = require('aws4') + , httpSignature = require('http-signature') + , mime = require('mime-types') + , stringstream = require('stringstream') + , caseless = require('caseless') + , ForeverAgent = require('forever-agent') + , FormData = require('form-data') + , extend = require('extend') + , isstream = require('isstream') + , isTypedArray = require('is-typedarray').strict + , helpers = require('./lib/helpers') + , cookies = require('./lib/cookies') + , getProxyFromURI = require('./lib/getProxyFromURI') + , Querystring = require('./lib/querystring').Querystring + , Har = require('./lib/har').Har + , Auth = require('./lib/auth').Auth + , OAuth = require('./lib/oauth').OAuth + , Multipart = require('./lib/multipart').Multipart + , Redirect = require('./lib/redirect').Redirect + , Tunnel = require('./lib/tunnel').Tunnel + , now = require('performance-now') + , Buffer = require('safe-buffer').Buffer + +var safeStringify = helpers.safeStringify + , isReadStream = helpers.isReadStream + , toBase64 = helpers.toBase64 + , defer = helpers.defer + , copy = helpers.copy + , version = helpers.version + , globalCookieJar = cookies.jar() + + +var globalPool = {} + +function filterForNonReserved(reserved, options) { + // Filter out properties that are not reserved. + // Reserved values are passed in at call site. + + var object = {} + for (var i in options) { + var notReserved = (reserved.indexOf(i) === -1) + if (notReserved) { + object[i] = options[i] + } + } + return object +} + +function filterOutReservedFunctions(reserved, options) { + // Filter out properties that are functions and are reserved. + // Reserved values are passed in at call site. + + var object = {} + for (var i in options) { + var isReserved = !(reserved.indexOf(i) === -1) + var isFunction = (typeof options[i] === 'function') + if (!(isReserved && isFunction)) { + object[i] = options[i] + } + } + return object + +} + +// Return a simpler request object to allow serialization +function requestToJSON() { + var self = this + return { + uri: self.uri, + method: self.method, + headers: self.headers + } +} + +// Return a simpler response object to allow serialization +function responseToJSON() { + var self = this + return { + statusCode: self.statusCode, + body: self.body, + headers: self.headers, + request: requestToJSON.call(self.request) + } +} + +function Request (options) { + // if given the method property in options, set property explicitMethod to true + + // extend the Request instance with any non-reserved properties + // remove any reserved functions from the options object + // set Request instance to be readable and writable + // call init + + var self = this + + // start with HAR, then override with additional options + if (options.har) { + self._har = new Har(self) + options = self._har.options(options) + } + + stream.Stream.call(self) + var reserved = Object.keys(Request.prototype) + var nonReserved = filterForNonReserved(reserved, options) + + extend(self, nonReserved) + options = filterOutReservedFunctions(reserved, options) + + self.readable = true + self.writable = true + if (options.method) { + self.explicitMethod = true + } + self._qs = new Querystring(self) + self._auth = new Auth(self) + self._oauth = new OAuth(self) + self._multipart = new Multipart(self) + self._redirect = new Redirect(self) + self._tunnel = new Tunnel(self) + self.init(options) +} + +util.inherits(Request, stream.Stream) + +// Debugging +Request.debug = process.env.NODE_DEBUG && /\brequest\b/.test(process.env.NODE_DEBUG) +function debug() { + if (Request.debug) { + console.error('REQUEST %s', util.format.apply(util, arguments)) + } +} +Request.prototype.debug = debug + +Request.prototype.init = function (options) { + // init() contains all the code to setup the request object. + // the actual outgoing request is not started until start() is called + // this function is called from both the constructor and on redirect. + var self = this + if (!options) { + options = {} + } + self.headers = self.headers ? copy(self.headers) : {} + + // Delete headers with value undefined since they break + // ClientRequest.OutgoingMessage.setHeader in node 0.12 + for (var headerName in self.headers) { + if (typeof self.headers[headerName] === 'undefined') { + delete self.headers[headerName] + } + } + + caseless.httpify(self, self.headers) + + if (!self.method) { + self.method = options.method || 'GET' + } + if (!self.localAddress) { + self.localAddress = options.localAddress + } + + self._qs.init(options) + + debug(options) + if (!self.pool && self.pool !== false) { + self.pool = globalPool + } + self.dests = self.dests || [] + self.__isRequestRequest = true + + // Protect against double callback + if (!self._callback && self.callback) { + self._callback = self.callback + self.callback = function () { + if (self._callbackCalled) { + return // Print a warning maybe? + } + self._callbackCalled = true + self._callback.apply(self, arguments) + } + self.on('error', self.callback.bind()) + self.on('complete', self.callback.bind(self, null)) + } + + // People use this property instead all the time, so support it + if (!self.uri && self.url) { + self.uri = self.url + delete self.url + } + + // If there's a baseUrl, then use it as the base URL (i.e. uri must be + // specified as a relative path and is appended to baseUrl). + if (self.baseUrl) { + if (typeof self.baseUrl !== 'string') { + return self.emit('error', new Error('options.baseUrl must be a string')) + } + + if (typeof self.uri !== 'string') { + return self.emit('error', new Error('options.uri must be a string when using options.baseUrl')) + } + + if (self.uri.indexOf('//') === 0 || self.uri.indexOf('://') !== -1) { + return self.emit('error', new Error('options.uri must be a path when using options.baseUrl')) + } + + // Handle all cases to make sure that there's only one slash between + // baseUrl and uri. + var baseUrlEndsWithSlash = self.baseUrl.lastIndexOf('/') === self.baseUrl.length - 1 + var uriStartsWithSlash = self.uri.indexOf('/') === 0 + + if (baseUrlEndsWithSlash && uriStartsWithSlash) { + self.uri = self.baseUrl + self.uri.slice(1) + } else if (baseUrlEndsWithSlash || uriStartsWithSlash) { + self.uri = self.baseUrl + self.uri + } else if (self.uri === '') { + self.uri = self.baseUrl + } else { + self.uri = self.baseUrl + '/' + self.uri + } + delete self.baseUrl + } + + // A URI is needed by this point, emit error if we haven't been able to get one + if (!self.uri) { + return self.emit('error', new Error('options.uri is a required argument')) + } + + // If a string URI/URL was given, parse it into a URL object + if (typeof self.uri === 'string') { + self.uri = url.parse(self.uri) + } + + // Some URL objects are not from a URL parsed string and need href added + if (!self.uri.href) { + self.uri.href = url.format(self.uri) + } + + // DEPRECATED: Warning for users of the old Unix Sockets URL Scheme + if (self.uri.protocol === 'unix:') { + return self.emit('error', new Error('`unix://` URL scheme is no longer supported. Please use the format `http://unix:SOCKET:PATH`')) + } + + // Support Unix Sockets + if (self.uri.host === 'unix') { + self.enableUnixSocket() + } + + if (self.strictSSL === false) { + self.rejectUnauthorized = false + } + + if (!self.uri.pathname) {self.uri.pathname = '/'} + + if (!(self.uri.host || (self.uri.hostname && self.uri.port)) && !self.uri.isUnix) { + // Invalid URI: it may generate lot of bad errors, like 'TypeError: Cannot call method `indexOf` of undefined' in CookieJar + // Detect and reject it as soon as possible + var faultyUri = url.format(self.uri) + var message = 'Invalid URI "' + faultyUri + '"' + if (Object.keys(options).length === 0) { + // No option ? This can be the sign of a redirect + // As this is a case where the user cannot do anything (they didn't call request directly with this URL) + // they should be warned that it can be caused by a redirection (can save some hair) + message += '. This can be caused by a crappy redirection.' + } + // This error was fatal + self.abort() + return self.emit('error', new Error(message)) + } + + if (!self.hasOwnProperty('proxy')) { + self.proxy = getProxyFromURI(self.uri) + } + + self.tunnel = self._tunnel.isEnabled() + if (self.proxy) { + self._tunnel.setup(options) + } + + self._redirect.onRequest(options) + + self.setHost = false + if (!self.hasHeader('host')) { + var hostHeaderName = self.originalHostHeaderName || 'host' + // When used with an IPv6 address, `host` will provide + // the correct bracketed format, unlike using `hostname` and + // optionally adding the `port` when necessary. + self.setHeader(hostHeaderName, self.uri.host) + self.setHost = true + } + + self.jar(self._jar || options.jar) + + if (!self.uri.port) { + if (self.uri.protocol === 'http:') {self.uri.port = 80} + else if (self.uri.protocol === 'https:') {self.uri.port = 443} + } + + if (self.proxy && !self.tunnel) { + self.port = self.proxy.port + self.host = self.proxy.hostname + } else { + self.port = self.uri.port + self.host = self.uri.hostname + } + + if (options.form) { + self.form(options.form) + } + + if (options.formData) { + var formData = options.formData + var requestForm = self.form() + var appendFormValue = function (key, value) { + if (value && value.hasOwnProperty('value') && value.hasOwnProperty('options')) { + requestForm.append(key, value.value, value.options) + } else { + requestForm.append(key, value) + } + } + for (var formKey in formData) { + if (formData.hasOwnProperty(formKey)) { + var formValue = formData[formKey] + if (formValue instanceof Array) { + for (var j = 0; j < formValue.length; j++) { + appendFormValue(formKey, formValue[j]) + } + } else { + appendFormValue(formKey, formValue) + } + } + } + } + + if (options.qs) { + self.qs(options.qs) + } + + if (self.uri.path) { + self.path = self.uri.path + } else { + self.path = self.uri.pathname + (self.uri.search || '') + } + + if (self.path.length === 0) { + self.path = '/' + } + + // Auth must happen last in case signing is dependent on other headers + if (options.aws) { + self.aws(options.aws) + } + + if (options.hawk) { + self.hawk(options.hawk) + } + + if (options.httpSignature) { + self.httpSignature(options.httpSignature) + } + + if (options.auth) { + if (Object.prototype.hasOwnProperty.call(options.auth, 'username')) { + options.auth.user = options.auth.username + } + if (Object.prototype.hasOwnProperty.call(options.auth, 'password')) { + options.auth.pass = options.auth.password + } + + self.auth( + options.auth.user, + options.auth.pass, + options.auth.sendImmediately, + options.auth.bearer + ) + } + + if (self.gzip && !self.hasHeader('accept-encoding')) { + self.setHeader('accept-encoding', 'gzip, deflate') + } + + if (self.uri.auth && !self.hasHeader('authorization')) { + var uriAuthPieces = self.uri.auth.split(':').map(function(item) {return self._qs.unescape(item)}) + self.auth(uriAuthPieces[0], uriAuthPieces.slice(1).join(':'), true) + } + + if (!self.tunnel && self.proxy && self.proxy.auth && !self.hasHeader('proxy-authorization')) { + var proxyAuthPieces = self.proxy.auth.split(':').map(function(item) {return self._qs.unescape(item)}) + var authHeader = 'Basic ' + toBase64(proxyAuthPieces.join(':')) + self.setHeader('proxy-authorization', authHeader) + } + + if (self.proxy && !self.tunnel) { + self.path = (self.uri.protocol + '//' + self.uri.host + self.path) + } + + if (options.json) { + self.json(options.json) + } + if (options.multipart) { + self.multipart(options.multipart) + } + + if (options.time) { + self.timing = true + + // NOTE: elapsedTime is deprecated in favor of .timings + self.elapsedTime = self.elapsedTime || 0 + } + + function setContentLength () { + if (isTypedArray(self.body)) { + self.body = Buffer.from(self.body) + } + + if (!self.hasHeader('content-length')) { + var length + if (typeof self.body === 'string') { + length = Buffer.byteLength(self.body) + } + else if (Array.isArray(self.body)) { + length = self.body.reduce(function (a, b) {return a + b.length}, 0) + } + else { + length = self.body.length + } + + if (length) { + self.setHeader('content-length', length) + } else { + self.emit('error', new Error('Argument error, options.body.')) + } + } + } + if (self.body && !isstream(self.body)) { + setContentLength() + } + + if (options.oauth) { + self.oauth(options.oauth) + } else if (self._oauth.params && self.hasHeader('authorization')) { + self.oauth(self._oauth.params) + } + + var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol + , defaultModules = {'http:':http, 'https:':https} + , httpModules = self.httpModules || {} + + self.httpModule = httpModules[protocol] || defaultModules[protocol] + + if (!self.httpModule) { + return self.emit('error', new Error('Invalid protocol: ' + protocol)) + } + + if (options.ca) { + self.ca = options.ca + } + + if (!self.agent) { + if (options.agentOptions) { + self.agentOptions = options.agentOptions + } + + if (options.agentClass) { + self.agentClass = options.agentClass + } else if (options.forever) { + var v = version() + // use ForeverAgent in node 0.10- only + if (v.major === 0 && v.minor <= 10) { + self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL + } else { + self.agentClass = self.httpModule.Agent + self.agentOptions = self.agentOptions || {} + self.agentOptions.keepAlive = true + } + } else { + self.agentClass = self.httpModule.Agent + } + } + + if (self.pool === false) { + self.agent = false + } else { + self.agent = self.agent || self.getNewAgent() + } + + self.on('pipe', function (src) { + if (self.ntick && self._started) { + self.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.')) + } + self.src = src + if (isReadStream(src)) { + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', mime.lookup(src.path)) + } + } else { + if (src.headers) { + for (var i in src.headers) { + if (!self.hasHeader(i)) { + self.setHeader(i, src.headers[i]) + } + } + } + if (self._json && !self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + if (src.method && !self.explicitMethod) { + self.method = src.method + } + } + + // self.on('pipe', function () { + // console.error('You have already piped to this stream. Pipeing twice is likely to break the request.') + // }) + }) + + defer(function () { + if (self._aborted) { + return + } + + var end = function () { + if (self._form) { + if (!self._auth.hasAuth) { + self._form.pipe(self) + } + else if (self._auth.hasAuth && self._auth.sentAuth) { + self._form.pipe(self) + } + } + if (self._multipart && self._multipart.chunked) { + self._multipart.body.pipe(self) + } + if (self.body) { + if (isstream(self.body)) { + self.body.pipe(self) + } else { + setContentLength() + if (Array.isArray(self.body)) { + self.body.forEach(function (part) { + self.write(part) + }) + } else { + self.write(self.body) + } + self.end() + } + } else if (self.requestBodyStream) { + console.warn('options.requestBodyStream is deprecated, please pass the request object to stream.pipe.') + self.requestBodyStream.pipe(self) + } else if (!self.src) { + if (self._auth.hasAuth && !self._auth.sentAuth) { + self.end() + return + } + if (self.method !== 'GET' && typeof self.method !== 'undefined') { + self.setHeader('content-length', 0) + } + self.end() + } + } + + if (self._form && !self.hasHeader('content-length')) { + // Before ending the request, we had to compute the length of the whole form, asyncly + self.setHeader(self._form.getHeaders(), true) + self._form.getLength(function (err, length) { + if (!err && !isNaN(length)) { + self.setHeader('content-length', length) + } + end() + }) + } else { + end() + } + + self.ntick = true + }) + +} + +Request.prototype.getNewAgent = function () { + var self = this + var Agent = self.agentClass + var options = {} + if (self.agentOptions) { + for (var i in self.agentOptions) { + options[i] = self.agentOptions[i] + } + } + if (self.ca) { + options.ca = self.ca + } + if (self.ciphers) { + options.ciphers = self.ciphers + } + if (self.secureProtocol) { + options.secureProtocol = self.secureProtocol + } + if (self.secureOptions) { + options.secureOptions = self.secureOptions + } + if (typeof self.rejectUnauthorized !== 'undefined') { + options.rejectUnauthorized = self.rejectUnauthorized + } + + if (self.cert && self.key) { + options.key = self.key + options.cert = self.cert + } + + if (self.pfx) { + options.pfx = self.pfx + } + + if (self.passphrase) { + options.passphrase = self.passphrase + } + + var poolKey = '' + + // different types of agents are in different pools + if (Agent !== self.httpModule.Agent) { + poolKey += Agent.name + } + + // ca option is only relevant if proxy or destination are https + var proxy = self.proxy + if (typeof proxy === 'string') { + proxy = url.parse(proxy) + } + var isHttps = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' + + if (isHttps) { + if (options.ca) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.ca + } + + if (typeof options.rejectUnauthorized !== 'undefined') { + if (poolKey) { + poolKey += ':' + } + poolKey += options.rejectUnauthorized + } + + if (options.cert) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.cert.toString('ascii') + options.key.toString('ascii') + } + + if (options.pfx) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.pfx.toString('ascii') + } + + if (options.ciphers) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.ciphers + } + + if (options.secureProtocol) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.secureProtocol + } + + if (options.secureOptions) { + if (poolKey) { + poolKey += ':' + } + poolKey += options.secureOptions + } + } + + if (self.pool === globalPool && !poolKey && Object.keys(options).length === 0 && self.httpModule.globalAgent) { + // not doing anything special. Use the globalAgent + return self.httpModule.globalAgent + } + + // we're using a stored agent. Make sure it's protocol-specific + poolKey = self.uri.protocol + poolKey + + // generate a new agent for this setting if none yet exists + if (!self.pool[poolKey]) { + self.pool[poolKey] = new Agent(options) + // properly set maxSockets on new agents + if (self.pool.maxSockets) { + self.pool[poolKey].maxSockets = self.pool.maxSockets + } + } + + return self.pool[poolKey] +} + +Request.prototype.start = function () { + // start() is called once we are ready to send the outgoing HTTP request. + // this is usually called on the first write(), end() or on nextTick() + var self = this + + if (self.timing) { + // All timings will be relative to this request's startTime. In order to do this, + // we need to capture the wall-clock start time (via Date), immediately followed + // by the high-resolution timer (via now()). While these two won't be set + // at the _exact_ same time, they should be close enough to be able to calculate + // high-resolution, monotonically non-decreasing timestamps relative to startTime. + var startTime = new Date().getTime() + var startTimeNow = now() + } + + if (self._aborted) { + return + } + + self._started = true + self.method = self.method || 'GET' + self.href = self.uri.href + + if (self.src && self.src.stat && self.src.stat.size && !self.hasHeader('content-length')) { + self.setHeader('content-length', self.src.stat.size) + } + if (self._aws) { + self.aws(self._aws, true) + } + + // We have a method named auth, which is completely different from the http.request + // auth option. If we don't remove it, we're gonna have a bad time. + var reqOptions = copy(self) + delete reqOptions.auth + + debug('make request', self.uri.href) + + // node v6.8.0 now supports a `timeout` value in `http.request()`, but we + // should delete it for now since we handle timeouts manually for better + // consistency with node versions before v6.8.0 + delete reqOptions.timeout + + try { + self.req = self.httpModule.request(reqOptions) + } catch (err) { + self.emit('error', err) + return + } + + if (self.timing) { + self.startTime = startTime + self.startTimeNow = startTimeNow + + // Timing values will all be relative to startTime (by comparing to startTimeNow + // so we have an accurate clock) + self.timings = {} + } + + var timeout + if (self.timeout && !self.timeoutTimer) { + if (self.timeout < 0) { + timeout = 0 + } else if (typeof self.timeout === 'number' && isFinite(self.timeout)) { + timeout = self.timeout + } + } + + self.req.on('response', self.onRequestResponse.bind(self)) + self.req.on('error', self.onRequestError.bind(self)) + self.req.on('drain', function() { + self.emit('drain') + }) + self.req.on('socket', function(socket) { + // `._connecting` was the old property which was made public in node v6.1.0 + var isConnecting = socket._connecting || socket.connecting + if (self.timing) { + self.timings.socket = now() - self.startTimeNow + + if (isConnecting) { + var onLookupTiming = function() { + self.timings.lookup = now() - self.startTimeNow + } + + var onConnectTiming = function() { + self.timings.connect = now() - self.startTimeNow + } + + socket.once('lookup', onLookupTiming) + socket.once('connect', onConnectTiming) + + // clean up timing event listeners if needed on error + self.req.once('error', function() { + socket.removeListener('lookup', onLookupTiming) + socket.removeListener('connect', onConnectTiming) + }) + } + } + + var setReqTimeout = function() { + // This timeout sets the amount of time to wait *between* bytes sent + // from the server once connected. + // + // In particular, it's useful for erroring if the server fails to send + // data halfway through streaming a response. + self.req.setTimeout(timeout, function () { + if (self.req) { + self.abort() + var e = new Error('ESOCKETTIMEDOUT') + e.code = 'ESOCKETTIMEDOUT' + e.connect = false + self.emit('error', e) + } + }) + } + if (timeout !== undefined) { + // Only start the connection timer if we're actually connecting a new + // socket, otherwise if we're already connected (because this is a + // keep-alive connection) do not bother. This is important since we won't + // get a 'connect' event for an already connected socket. + if (isConnecting) { + var onReqSockConnect = function() { + socket.removeListener('connect', onReqSockConnect) + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + setReqTimeout() + } + + socket.on('connect', onReqSockConnect) + + self.req.on('error', function(err) { + socket.removeListener('connect', onReqSockConnect) + }) + + // Set a timeout in memory - this block will throw if the server takes more + // than `timeout` to write the HTTP status and headers (corresponding to + // the on('response') event on the client). NB: this measures wall-clock + // time, not the time between bytes sent by the server. + self.timeoutTimer = setTimeout(function () { + socket.removeListener('connect', onReqSockConnect) + self.abort() + var e = new Error('ETIMEDOUT') + e.code = 'ETIMEDOUT' + e.connect = true + self.emit('error', e) + }, timeout) + } else { + // We're already connected + setReqTimeout() + } + } + self.emit('socket', socket) + }) + + self.emit('request', self.req) +} + +Request.prototype.onRequestError = function (error) { + var self = this + if (self._aborted) { + return + } + if (self.req && self.req._reusedSocket && error.code === 'ECONNRESET' + && self.agent.addRequestNoreuse) { + self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) } + self.start() + self.req.end() + return + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + self.emit('error', error) +} + +Request.prototype.onRequestResponse = function (response) { + var self = this + + if (self.timing) { + self.timings.response = now() - self.startTimeNow + } + + debug('onRequestResponse', self.uri.href, response.statusCode, response.headers) + response.on('end', function() { + if (self.timing) { + self.timings.end = now() - self.startTimeNow + response.timingStart = self.startTime + + // fill in the blanks for any periods that didn't trigger, such as + // no lookup or connect due to keep alive + if (!self.timings.socket) { + self.timings.socket = 0 + } + if (!self.timings.lookup) { + self.timings.lookup = self.timings.socket + } + if (!self.timings.connect) { + self.timings.connect = self.timings.lookup + } + if (!self.timings.response) { + self.timings.response = self.timings.connect + } + + debug('elapsed time', self.timings.end) + + // elapsedTime includes all redirects + self.elapsedTime += Math.round(self.timings.end) + + // NOTE: elapsedTime is deprecated in favor of .timings + response.elapsedTime = self.elapsedTime + + // timings is just for the final fetch + response.timings = self.timings + + // pre-calculate phase timings as well + response.timingPhases = { + wait: self.timings.socket, + dns: self.timings.lookup - self.timings.socket, + tcp: self.timings.connect - self.timings.lookup, + firstByte: self.timings.response - self.timings.connect, + download: self.timings.end - self.timings.response, + total: self.timings.end + } + } + debug('response end', self.uri.href, response.statusCode, response.headers) + }) + + if (self._aborted) { + debug('aborted', self.uri.href) + response.resume() + return + } + + self.response = response + response.request = self + response.toJSON = responseToJSON + + // XXX This is different on 0.10, because SSL is strict by default + if (self.httpModule === https && + self.strictSSL && (!response.hasOwnProperty('socket') || + !response.socket.authorized)) { + debug('strict ssl error', self.uri.href) + var sslErr = response.hasOwnProperty('socket') ? response.socket.authorizationError : self.uri.href + ' does not support SSL' + self.emit('error', new Error('SSL Error: ' + sslErr)) + return + } + + // Save the original host before any redirect (if it changes, we need to + // remove any authorization headers). Also remember the case of the header + // name because lots of broken servers expect Host instead of host and we + // want the caller to be able to specify this. + self.originalHost = self.getHeader('host') + if (!self.originalHostHeaderName) { + self.originalHostHeaderName = self.hasHeader('host') + } + if (self.setHost) { + self.removeHeader('host') + } + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer) + self.timeoutTimer = null + } + + var targetCookieJar = (self._jar && self._jar.setCookie) ? self._jar : globalCookieJar + var addCookie = function (cookie) { + //set the cookie if it's domain in the href's domain. + try { + targetCookieJar.setCookie(cookie, self.uri.href, {ignoreError: true}) + } catch (e) { + self.emit('error', e) + } + } + + response.caseless = caseless(response.headers) + + if (response.caseless.has('set-cookie') && (!self._disableCookies)) { + var headerName = response.caseless.has('set-cookie') + if (Array.isArray(response.headers[headerName])) { + response.headers[headerName].forEach(addCookie) + } else { + addCookie(response.headers[headerName]) + } + } + + if (self._redirect.onResponse(response)) { + return // Ignore the rest of the response + } else { + // Be a good stream and emit end when the response is finished. + // Hack to emit end on close because of a core bug that never fires end + response.on('close', function () { + if (!self._ended) { + self.response.emit('end') + } + }) + + response.once('end', function () { + self._ended = true + }) + + var noBody = function (code) { + return ( + self.method === 'HEAD' + // Informational + || (code >= 100 && code < 200) + // No Content + || code === 204 + // Not Modified + || code === 304 + ) + } + + var responseContent + if (self.gzip && !noBody(response.statusCode)) { + var contentEncoding = response.headers['content-encoding'] || 'identity' + contentEncoding = contentEncoding.trim().toLowerCase() + + // Be more lenient with decoding compressed responses, since (very rarely) + // servers send slightly invalid gzip responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + var zlibOptions = { + flush: zlib.Z_SYNC_FLUSH + , finishFlush: zlib.Z_SYNC_FLUSH + } + + if (contentEncoding === 'gzip') { + responseContent = zlib.createGunzip(zlibOptions) + response.pipe(responseContent) + } else if (contentEncoding === 'deflate') { + responseContent = zlib.createInflate(zlibOptions) + response.pipe(responseContent) + } else { + // Since previous versions didn't check for Content-Encoding header, + // ignore any invalid values to preserve backwards-compatibility + if (contentEncoding !== 'identity') { + debug('ignoring unrecognized Content-Encoding ' + contentEncoding) + } + responseContent = response + } + } else { + responseContent = response + } + + if (self.encoding) { + if (self.dests.length !== 0) { + console.error('Ignoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.') + } else if (responseContent.setEncoding) { + responseContent.setEncoding(self.encoding) + } else { + // Should only occur on node pre-v0.9.4 (joyent/node@9b5abe5) with + // zlib streams. + // If/When support for 0.9.4 is dropped, this should be unnecessary. + responseContent = responseContent.pipe(stringstream(self.encoding)) + } + } + + if (self._paused) { + responseContent.pause() + } + + self.responseContent = responseContent + + self.emit('response', response) + + self.dests.forEach(function (dest) { + self.pipeDest(dest) + }) + + responseContent.on('data', function (chunk) { + if (self.timing && !self.responseStarted) { + self.responseStartTime = (new Date()).getTime() + + // NOTE: responseStartTime is deprecated in favor of .timings + response.responseStartTime = self.responseStartTime + } + self._destdata = true + self.emit('data', chunk) + }) + responseContent.once('end', function (chunk) { + self.emit('end', chunk) + }) + responseContent.on('error', function (error) { + self.emit('error', error) + }) + responseContent.on('close', function () {self.emit('close')}) + + if (self.callback) { + self.readResponseBody(response) + } + //if no callback + else { + self.on('end', function () { + if (self._aborted) { + debug('aborted', self.uri.href) + return + } + self.emit('complete', response) + }) + } + } + debug('finish init function', self.uri.href) +} + +Request.prototype.readResponseBody = function (response) { + var self = this + debug('reading response\'s body') + var buffers = [] + , bufferLength = 0 + , strings = [] + + self.on('data', function (chunk) { + if (!Buffer.isBuffer(chunk)) { + strings.push(chunk) + } else if (chunk.length) { + bufferLength += chunk.length + buffers.push(chunk) + } + }) + self.on('end', function () { + debug('end event', self.uri.href) + if (self._aborted) { + debug('aborted', self.uri.href) + // `buffer` is defined in the parent scope and used in a closure it exists for the life of the request. + // This can lead to leaky behavior if the user retains a reference to the request object. + buffers = [] + bufferLength = 0 + return + } + + if (bufferLength) { + debug('has body', self.uri.href, bufferLength) + response.body = Buffer.concat(buffers, bufferLength) + if (self.encoding !== null) { + response.body = response.body.toString(self.encoding) + } + // `buffer` is defined in the parent scope and used in a closure it exists for the life of the Request. + // This can lead to leaky behavior if the user retains a reference to the request object. + buffers = [] + bufferLength = 0 + } else if (strings.length) { + // The UTF8 BOM [0xEF,0xBB,0xBF] is converted to [0xFE,0xFF] in the JS UTC16/UCS2 representation. + // Strip this value out when the encoding is set to 'utf8', as upstream consumers won't expect it and it breaks JSON.parse(). + if (self.encoding === 'utf8' && strings[0].length > 0 && strings[0][0] === '\uFEFF') { + strings[0] = strings[0].substring(1) + } + response.body = strings.join('') + } + + if (self._json) { + try { + response.body = JSON.parse(response.body, self._jsonReviver) + } catch (e) { + debug('invalid JSON received', self.uri.href) + } + } + debug('emitting complete', self.uri.href) + if (typeof response.body === 'undefined' && !self._json) { + response.body = self.encoding === null ? Buffer.alloc(0) : '' + } + self.emit('complete', response, response.body) + }) +} + +Request.prototype.abort = function () { + var self = this + self._aborted = true + + if (self.req) { + self.req.abort() + } + else if (self.response) { + self.response.destroy() + } + + self.emit('abort') +} + +Request.prototype.pipeDest = function (dest) { + var self = this + var response = self.response + // Called after the response is received + if (dest.headers && !dest.headersSent) { + if (response.caseless.has('content-type')) { + var ctname = response.caseless.has('content-type') + if (dest.setHeader) { + dest.setHeader(ctname, response.headers[ctname]) + } + else { + dest.headers[ctname] = response.headers[ctname] + } + } + + if (response.caseless.has('content-length')) { + var clname = response.caseless.has('content-length') + if (dest.setHeader) { + dest.setHeader(clname, response.headers[clname]) + } else { + dest.headers[clname] = response.headers[clname] + } + } + } + if (dest.setHeader && !dest.headersSent) { + for (var i in response.headers) { + // If the response content is being decoded, the Content-Encoding header + // of the response doesn't represent the piped content, so don't pass it. + if (!self.gzip || i !== 'content-encoding') { + dest.setHeader(i, response.headers[i]) + } + } + dest.statusCode = response.statusCode + } + if (self.pipefilter) { + self.pipefilter(response, dest) + } +} + +Request.prototype.qs = function (q, clobber) { + var self = this + var base + if (!clobber && self.uri.query) { + base = self._qs.parse(self.uri.query) + } else { + base = {} + } + + for (var i in q) { + base[i] = q[i] + } + + var qs = self._qs.stringify(base) + + if (qs === '') { + return self + } + + self.uri = url.parse(self.uri.href.split('?')[0] + '?' + qs) + self.url = self.uri + self.path = self.uri.path + + if (self.uri.host === 'unix') { + self.enableUnixSocket() + } + + return self +} +Request.prototype.form = function (form) { + var self = this + if (form) { + if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { + self.setHeader('content-type', 'application/x-www-form-urlencoded') + } + self.body = (typeof form === 'string') + ? self._qs.rfc3986(form.toString('utf8')) + : self._qs.stringify(form).toString('utf8') + return self + } + // create form-data object + self._form = new FormData() + self._form.on('error', function(err) { + err.message = 'form-data: ' + err.message + self.emit('error', err) + self.abort() + }) + return self._form +} +Request.prototype.multipart = function (multipart) { + var self = this + + self._multipart.onRequest(multipart) + + if (!self._multipart.chunked) { + self.body = self._multipart.body + } + + return self +} +Request.prototype.json = function (val) { + var self = this + + if (!self.hasHeader('accept')) { + self.setHeader('accept', 'application/json') + } + + if (typeof self.jsonReplacer === 'function') { + self._jsonReplacer = self.jsonReplacer + } + + self._json = true + if (typeof val === 'boolean') { + if (self.body !== undefined) { + if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { + self.body = safeStringify(self.body, self._jsonReplacer) + } else { + self.body = self._qs.rfc3986(self.body) + } + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + } + } else { + self.body = safeStringify(val, self._jsonReplacer) + if (!self.hasHeader('content-type')) { + self.setHeader('content-type', 'application/json') + } + } + + if (typeof self.jsonReviver === 'function') { + self._jsonReviver = self.jsonReviver + } + + return self +} +Request.prototype.getHeader = function (name, headers) { + var self = this + var result, re, match + if (!headers) { + headers = self.headers + } + Object.keys(headers).forEach(function (key) { + if (key.length !== name.length) { + return + } + re = new RegExp(name, 'i') + match = key.match(re) + if (match) { + result = headers[key] + } + }) + return result +} +Request.prototype.enableUnixSocket = function () { + // Get the socket & request paths from the URL + var unixParts = this.uri.path.split(':') + , host = unixParts[0] + , path = unixParts[1] + // Apply unix properties to request + this.socketPath = host + this.uri.pathname = path + this.uri.path = path + this.uri.host = host + this.uri.hostname = host + this.uri.isUnix = true +} + + +Request.prototype.auth = function (user, pass, sendImmediately, bearer) { + var self = this + + self._auth.onRequest(user, pass, sendImmediately, bearer) + + return self +} +Request.prototype.aws = function (opts, now) { + var self = this + + if (!now) { + self._aws = opts + return self + } + + if (opts.sign_version == 4 || opts.sign_version == '4') { + // use aws4 + var options = { + host: self.uri.host, + path: self.uri.path, + method: self.method, + headers: { + 'content-type': self.getHeader('content-type') || '' + }, + body: self.body + } + var signRes = aws4.sign(options, { + accessKeyId: opts.key, + secretAccessKey: opts.secret, + sessionToken: opts.session + }) + self.setHeader('authorization', signRes.headers.Authorization) + self.setHeader('x-amz-date', signRes.headers['X-Amz-Date']) + if (signRes.headers['X-Amz-Security-Token']) { + self.setHeader('x-amz-security-token', signRes.headers['X-Amz-Security-Token']) + } + } + else { + // default: use aws-sign2 + var date = new Date() + self.setHeader('date', date.toUTCString()) + var auth = + { key: opts.key + , secret: opts.secret + , verb: self.method.toUpperCase() + , date: date + , contentType: self.getHeader('content-type') || '' + , md5: self.getHeader('content-md5') || '' + , amazonHeaders: aws2.canonicalizeHeaders(self.headers) + } + var path = self.uri.path + if (opts.bucket && path) { + auth.resource = '/' + opts.bucket + path + } else if (opts.bucket && !path) { + auth.resource = '/' + opts.bucket + } else if (!opts.bucket && path) { + auth.resource = path + } else if (!opts.bucket && !path) { + auth.resource = '/' + } + auth.resource = aws2.canonicalizeResource(auth.resource) + self.setHeader('authorization', aws2.authorization(auth)) + } + + return self +} +Request.prototype.httpSignature = function (opts) { + var self = this + httpSignature.signRequest({ + getHeader: function(header) { + return self.getHeader(header, self.headers) + }, + setHeader: function(header, value) { + self.setHeader(header, value) + }, + method: self.method, + path: self.path + }, opts) + debug('httpSignature authorization', self.getHeader('authorization')) + + return self +} +Request.prototype.hawk = function (opts) { + var self = this + self.setHeader('Authorization', hawk.client.header(self.uri, self.method, opts).field) +} +Request.prototype.oauth = function (_oauth) { + var self = this + + self._oauth.onRequest(_oauth) + + return self +} + +Request.prototype.jar = function (jar) { + var self = this + var cookies + + if (self._redirect.redirectsFollowed === 0) { + self.originalCookieHeader = self.getHeader('cookie') + } + + if (!jar) { + // disable cookies + cookies = false + self._disableCookies = true + } else { + var targetCookieJar = (jar && jar.getCookieString) ? jar : globalCookieJar + var urihref = self.uri.href + //fetch cookie in the Specified host + if (targetCookieJar) { + cookies = targetCookieJar.getCookieString(urihref) + } + } + + //if need cookie and cookie is not empty + if (cookies && cookies.length) { + if (self.originalCookieHeader) { + // Don't overwrite existing Cookie header + self.setHeader('cookie', self.originalCookieHeader + '; ' + cookies) + } else { + self.setHeader('cookie', cookies) + } + } + self._jar = jar + return self +} + + +// Stream API +Request.prototype.pipe = function (dest, opts) { + var self = this + + if (self.response) { + if (self._destdata) { + self.emit('error', new Error('You cannot pipe after data has been emitted from the response.')) + } else if (self._ended) { + self.emit('error', new Error('You cannot pipe after the response has been ended.')) + } else { + stream.Stream.prototype.pipe.call(self, dest, opts) + self.pipeDest(dest) + return dest + } + } else { + self.dests.push(dest) + stream.Stream.prototype.pipe.call(self, dest, opts) + return dest + } +} +Request.prototype.write = function () { + var self = this + if (self._aborted) {return} + + if (!self._started) { + self.start() + } + if (self.req) { + return self.req.write.apply(self.req, arguments) + } +} +Request.prototype.end = function (chunk) { + var self = this + if (self._aborted) {return} + + if (chunk) { + self.write(chunk) + } + if (!self._started) { + self.start() + } + if (self.req) { + self.req.end() + } +} +Request.prototype.pause = function () { + var self = this + if (!self.responseContent) { + self._paused = true + } else { + self.responseContent.pause.apply(self.responseContent, arguments) + } +} +Request.prototype.resume = function () { + var self = this + if (!self.responseContent) { + self._paused = false + } else { + self.responseContent.resume.apply(self.responseContent, arguments) + } +} +Request.prototype.destroy = function () { + var self = this + if (!self._ended) { + self.end() + } else if (self.response) { + self.response.destroy() + } +} + +Request.defaultProxyHeaderWhiteList = + Tunnel.defaultProxyHeaderWhiteList.slice() + +Request.defaultProxyHeaderExclusiveList = + Tunnel.defaultProxyHeaderExclusiveList.slice() + +// Exports + +Request.prototype.toJSON = requestToJSON +module.exports = Request diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/walk/README.md b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/README.md new file mode 100644 index 0000000000..c323d8a689 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/README.md @@ -0,0 +1,307 @@ +node-walk +==== + +nodejs walk implementation. + +This is somewhat of a port python's `os.walk`, but using Node.JS conventions. + + * EventEmitter + * Asynchronous + * Chronological (optionally) + * Built-in flow-control + * includes Synchronous version (same API as Asynchronous) + +As few file descriptors are opened at a time as possible. +This is particularly well suited for single hard disks which are not flash or solid state. + +Installation +---- + +```bash +npm install --save walk +``` + +Getting Started +==== + +```javascript +(function () { + "use strict"; + + var walk = require('walk') + , fs = require('fs') + , walker + ; + + walker = walk.walk("/tmp", options); + + walker.on("file", function (root, fileStats, next) { + fs.readFile(fileStats.name, function () { + // doStuff + next(); + }); + }); + + walker.on("errors", function (root, nodeStatsArray, next) { + next(); + }); + + walker.on("end", function () { + console.log("all done"); + }); +}()); +``` + +Common Events +----- + +All single event callbacks are in the form of `function (root, stat, next) {}`. + +All multiple event callbacks callbacks are in the form of `function (root, stats, next) {}`, except **names** which is an array of strings. + +All **error** event callbacks are in the form `function (root, stat/stats, next) {}`. +**`stat.error`** contains the error. + +* `names` +* `directory` +* `directories` +* `file` +* `files` +* `end` +* `nodeError` (`stat` failed) +* `directoryError` (`stat` succedded, but `readdir` failed) +* `errors` (a collection of any errors encountered) + + +A typical `stat` event looks like this: + +```javascript +{ dev: 16777223, + mode: 33188, + nlink: 1, + uid: 501, + gid: 20, + rdev: 0, + blksize: 4096, + ino: 49868100, + size: 5617, + blocks: 16, + atime: Mon Jan 05 2015 18:18:10 GMT-0700 (MST), + mtime: Thu Sep 25 2014 21:21:28 GMT-0600 (MDT), + ctime: Thu Sep 25 2014 21:21:28 GMT-0600 (MDT), + birthtime: Thu Sep 25 2014 21:21:28 GMT-0600 (MDT), + name: 'README.md', + type: 'file' } +``` + +Advanced Example +==== + +Both Asynchronous and Synchronous versions are provided. + +```javascript +(function () { + "use strict"; + + var walk = require('walk') + , fs = require('fs') + , options + , walker + ; + + options = { + followLinks: false + // directories with these keys will be skipped + , filters: ["Temp", "_Temp"] + }; + + walker = walk.walk("/tmp", options); + + // OR + // walker = walk.walkSync("/tmp", options); + + walker.on("names", function (root, nodeNamesArray) { + nodeNamesArray.sort(function (a, b) { + if (a > b) return 1; + if (a < b) return -1; + return 0; + }); + }); + + walker.on("directories", function (root, dirStatsArray, next) { + // dirStatsArray is an array of `stat` objects with the additional attributes + // * type + // * error + // * name + + next(); + }); + + walker.on("file", function (root, fileStats, next) { + fs.readFile(fileStats.name, function () { + // doStuff + next(); + }); + }); + + walker.on("errors", function (root, nodeStatsArray, next) { + next(); + }); + + walker.on("end", function () { + console.log("all done"); + }); +}()); +``` + +### Sync + +Note: You **can't use EventEmitter** if you want truly synchronous walker +(although it's synchronous under the hood, it appears not to be due to the use of `process.nextTick()`). + +Instead **you must use `options.listeners`** for truly synchronous walker. + +Although the sync version uses all of the `fs.readSync`, `fs.readdirSync`, and other sync methods, +I don't think I can prevent the `process.nextTick()` that `EventEmitter` calls. + +```javascript +(function () { + "use strict"; + + var walk = require('walk') + , fs = require('fs') + , options + , walker + ; + + // To be truly synchronous in the emitter and maintain a compatible api, + // the listeners must be listed before the object is created + options = { + listeners: { + names: function (root, nodeNamesArray) { + nodeNamesArray.sort(function (a, b) { + if (a > b) return 1; + if (a < b) return -1; + return 0; + }); + } + , directories: function (root, dirStatsArray, next) { + // dirStatsArray is an array of `stat` objects with the additional attributes + // * type + // * error + // * name + + next(); + } + , file: function (root, fileStats, next) { + fs.readFile(fileStats.name, function () { + // doStuff + next(); + }); + } + , errors: function (root, nodeStatsArray, next) { + next(); + } + } + }; + + walker = walk.walkSync("/tmp", options); + + console.log("all done"); +}()); +``` + +API +==== + +Emitted Values + + * `on('XYZ', function(root, stats, next) {})` + + * `root` - the containing the files to be inspected + * *stats[Array]* - a single `stats` object or an array with some added attributes + * type - 'file', 'directory', etc + * error + * name - the name of the file, dir, etc + * next - no more files will be read until this is called + +Single Events - fired immediately + + * `end` - No files, dirs, etc left to inspect + + * `directoryError` - Error when `fstat` succeeded, but reading path failed (Probably due to permissions). + * `nodeError` - Error `fstat` did not succeeded. + * `node` - a `stats` object for a node of any type + * `file` - includes links when `followLinks` is `true` + * `directory` - **NOTE** you could get a recursive loop if `followLinks` and a directory links to its parent + * `symbolicLink` - always empty when `followLinks` is `true` + * `blockDevice` + * `characterDevice` + * `FIFO` + * `socket` + +Events with Array Arguments - fired after all files in the dir have been `stat`ed + + * `names` - before any `stat` takes place. Useful for sorting and filtering. + * Note: the array is an array of `string`s, not `stat` objects + * Note: the `next` argument is a `noop` + + * `errors` - errors encountered by `fs.stat` when reading ndes in a directory + * `nodes` - an array of `stats` of any type + * `files` + * `directories` - modification of this array - sorting, removing, etc - affects traversal + * `symbolicLinks` + * `blockDevices` + * `characterDevices` + * `FIFOs` + * `sockets` + +**Warning** beware of infinite loops when `followLinks` is true (using `walk-recurse` varient). + +Comparisons +==== + +Tested on my `/System` containing 59,490 (+ self) directories (and lots of files). +The size of the text output was 6mb. + +`find`: + time bash -c "find /System -type d | wc" + 59491 97935 6262916 + + real 2m27.114s + user 0m1.193s + sys 0m14.859s + +`find.js`: + +Note that `find.js` omits the start directory + + time bash -c "node examples/find.js /System -type d | wc" + 59490 97934 6262908 + + # Test 1 + real 2m52.273s + user 0m20.374s + sys 0m27.800s + + # Test 2 + real 2m23.725s + user 0m18.019s + sys 0m23.202s + + # Test 3 + real 2m50.077s + user 0m17.661s + sys 0m24.008s + +In conclusion node.js asynchronous walk is much slower than regular "find". + +LICENSE +=== + +`node-walk` is available under the following licenses: + + * MIT + * Apache 2 + +Copyright 2011 - Present AJ ONeal diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/node-type-emitter.js b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/node-type-emitter.js new file mode 100644 index 0000000000..9a1e01c8b9 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/node-type-emitter.js @@ -0,0 +1,89 @@ +/*jshint strict:true node:true es5:true onevar:true laxcomma:true laxbreak:true*/ +(function () { + "use strict"; + + // "FIFO" isn't easy to convert to camelCase and back reliably + var isFnodeTypes = [ + "isFile", "isDirectory", "isSymbolicLink", "isBlockDevice", "isCharacterDevice", "isFIFO", "isSocket" + ], + fnodeTypes = [ + "file", "directory", "symbolicLink", "blockDevice", "characterDevice", "FIFO", "socket" + ], + fnodeTypesPlural = [ + "files", "directories", "symbolicLinks", "blockDevices", "characterDevices", "FIFOs", "sockets" + ]; + + + // + function createNodeGroups() { + var nodeGroups = {}; + fnodeTypesPlural.concat("nodes", "errors").forEach(function (fnodeTypePlural) { + nodeGroups[fnodeTypePlural] = []; + }); + return nodeGroups; + } + + + // Determine each file node's type + // + function sortFnodesByType(stat, fnodes) { + var i, isType; + + for (i = 0; i < isFnodeTypes.length; i += 1) { + isType = isFnodeTypes[i]; + if (stat[isType]()) { + stat.type = fnodeTypes[i]; + fnodes[fnodeTypesPlural[i]].push(stat); + return; + } + } + } + + + // Get the current number of listeners (which may change) + // Emit events to each listener + // Wait for all listeners to `next()` before continueing + // (in theory this may avoid disk thrashing) + function emitSingleEvents(emitter, path, stats, next, self) { + var num = 1 + emitter.listeners(stats.type).length + emitter.listeners("node").length; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next.call(self); } + } + + emitter.emit(stats.type, path, stats, nextWhenReady); + emitter.emit("node", path, stats, nextWhenReady); + nextWhenReady(); + } + + + // Since the risk for disk thrashing among anything + // other than files is relatively low, all types are + // emitted at once, but all must complete before advancing + function emitPluralEvents(emitter, path, nodes, next, self) { + var num = 1; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next.call(self); } + } + + fnodeTypesPlural.concat(["nodes", "errors"]).forEach(function (fnodeType) { + if (0 === nodes[fnodeType].length) { return; } + num += emitter.listeners(fnodeType).length; + emitter.emit(fnodeType, path, nodes[fnodeType], nextWhenReady); + }); + nextWhenReady(); + } + + module.exports = { + emitNodeType: emitSingleEvents, + emitNodeTypeGroups: emitPluralEvents, + isFnodeTypes: isFnodeTypes, + fnodeTypes: fnodeTypes, + fnodeTypesPlural: fnodeTypesPlural, + sortFnodesByType: sortFnodesByType, + createNodeGroups: createNodeGroups + }; +}()); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk-async-only.js b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk-async-only.js new file mode 100644 index 0000000000..41b30ca538 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk-async-only.js @@ -0,0 +1,93 @@ +(function () { + "use strict" + + // Array.prototype.forEachAsync(next, item, i, collection) + require('futures/forEachAsync'); + + function noop() {} + + var fs = require('fs'), + path = require('path'), + EventEmitter = require('events').EventEmitter, + TypeEmitter = require('./node-type-emitter'); + + // 2010-11-25 jorge@jorgechamorro.com + function create(pathname, cb) { + var emitter = new EventEmitter(), + q = [], + queue = [q], + curpath; + + function walk() { + fs.readdir(curpath, function(err, files) { + if (err) { + emitter.emit('directoryError', curpath, { error: err }, noop); + //emitter.emit('error', curpath, { error: err }); + } + // XXX bug was here. next() was omitted + if (!files || 0 == files.length) { + return next(); + } + + var fnodeGroups = TypeEmitter.createNodeGroups(); + + // TODO could allow user to selectively stat + // and don't stat if there are no stat listeners + emitter.emit('names', curpath, files, noop); + files.forEachAsync(function (cont, file) { + emitter.emit('name', curpath, file, noop); + fs.lstat(curpath + path.sep + file, function (err, stat) { + stat = stat || {}; + stat.name = file; + if (err) { + stat.error = err; + //emitter.emit('error', curpath, stat); + emitter.emit('nodeError', curpath, stat, noop); + fnodeGroups.errors.push(stat); + cont(); + } else { + TypeEmitter.sortFnodesByType(stat, fnodeGroups); + TypeEmitter.emitNodeType(emitter, curpath, stat, cont); + } + }); + }).then(function () { + if (fnodeGroups.errors.length) { + emitter.emit('errors', curpath, fnodeGroups.errors, noop); + } + TypeEmitter.emitNodeTypeGroups(emitter, curpath, fnodeGroups, function () { + var dirs = []; + fnodeGroups.directories.forEach(function (stat) { + dirs.push(stat.name); + }); + dirs.forEach(fullPath); + queue.push(q = dirs); + next(); + }); + }); + }); + } + + function next() { + if (q.length) { + curpath = q.pop(); + return walk(); + } + if (queue.length -= 1) { + q = queue[queue.length-1]; + return next(); + } + emitter.emit('end'); + } + + function fullPath(v,i,o) { + o[i]= [curpath, path.sep, v].join(''); + } + + curpath = pathname; + walk(); + + return emitter; + } + + module.exports = create; +}()); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk.js b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk.js new file mode 100644 index 0000000000..93c40ed26c --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/lib/walk.js @@ -0,0 +1,301 @@ +// Adapted from work by jorge@jorgechamorro.com on 2010-11-25 +(function () { + "use strict"; + + function noop() {} + + var fs = require('fs') + , forEachAsync = require('foreachasync').forEachAsync + , EventEmitter = require('events').EventEmitter + , TypeEmitter = require('./node-type-emitter') + , util = require('util') + , path = require('path') + ; + + function appendToDirs(stat) { + /*jshint validthis:true*/ + this.push(stat.name); + } + + function wFilesHandlerWrapper(items) { + /*jshint validthis:true*/ + this._wFilesHandler(noop, items); + } + + function Walker(pathname, options, sync) { + EventEmitter.call(this); + + var me = this + ; + + options = options || {}; + me._wStat = options.followLinks && 'stat' || 'lstat'; + me._wStatSync = me._wStat + 'Sync'; + me._wsync = sync; + me._wq = []; + me._wqueue = [me._wq]; + me._wcurpath = undefined; + me._wfilters = options.filters || []; + me._wfirstrun = true; + me._wcurpath = pathname; + + if (me._wsync) { + //console.log('_walkSync'); + me._wWalk = me._wWalkSync; + } else { + //console.log('_walkASync'); + me._wWalk = me._wWalkAsync; + } + + options.listeners = options.listeners || {}; + Object.keys(options.listeners).forEach(function (event) { + var callbacks = options.listeners[event] + ; + + if ('function' === typeof callbacks) { + callbacks = [callbacks]; + } + + callbacks.forEach(function (callback) { + me.on(event, callback); + }); + }); + + me._wWalk(); + } + + // Inherits must come before prototype additions + util.inherits(Walker, EventEmitter); + + Walker.prototype._wLstatHandler = function (err, stat) { + var me = this + ; + + stat = stat || {}; + stat.name = me._wcurfile; + + if (err) { + stat.error = err; + //me.emit('error', curpath, stat); + // TODO v3.0 (don't noop the next if there are listeners) + me.emit('nodeError', me._wcurpath, stat, noop); + me._wfnodegroups.errors.push(stat); + me._wCurFileCallback(); + } else { + TypeEmitter.sortFnodesByType(stat, me._wfnodegroups); + // NOTE: wCurFileCallback doesn't need thisness, so this is okay + TypeEmitter.emitNodeType(me, me._wcurpath, stat, me._wCurFileCallback, me); + } + }; + Walker.prototype._wFilesHandler = function (cont, file) { + var statPath + , me = this + ; + + + me._wcurfile = file; + me._wCurFileCallback = cont; + me.emit('name', me._wcurpath, file, noop); + + statPath = me._wcurpath + path.sep + file; + + if (!me._wsync) { + // TODO how to remove this anony? + fs[me._wStat](statPath, function (err, stat) { + me._wLstatHandler(err, stat); + }); + return; + } + + try { + me._wLstatHandler(null, fs[me._wStatSync](statPath)); + } catch(e) { + me._wLstatHandler(e); + } + }; + Walker.prototype._wOnEmitDone = function () { + var me = this + , dirs = [] + ; + + me._wfnodegroups.directories.forEach(appendToDirs, dirs); + dirs.forEach(me._wJoinPath, me); + me._wqueue.push(me._wq = dirs); + me._wNext(); + }; + Walker.prototype._wPostFilesHandler = function () { + var me = this + ; + + if (me._wfnodegroups.errors.length) { + // TODO v3.0 (don't noop the next) + // .errors is an array of stats with { name: name, error: error } + me.emit('errors', me._wcurpath, me._wfnodegroups.errors, noop); + } + // XXX emitNodeTypes still needs refactor + TypeEmitter.emitNodeTypeGroups(me, me._wcurpath, me._wfnodegroups, me._wOnEmitDone, me); + }; + Walker.prototype._wReadFiles = function () { + var me = this + ; + + if (!me._wcurfiles || 0 === me._wcurfiles.length) { + return me._wNext(); + } + + // TODO could allow user to selectively stat + // and don't stat if there are no stat listeners + me.emit('names', me._wcurpath, me._wcurfiles, noop); + + if (me._wsync) { + me._wcurfiles.forEach(wFilesHandlerWrapper, me); + me._wPostFilesHandler(); + } else { + forEachAsync(me._wcurfiles, me._wFilesHandler, me).then(me._wPostFilesHandler); + } + }; + Walker.prototype._wReaddirHandler = function (err, files) { + var fnodeGroups = TypeEmitter.createNodeGroups() + , me = this + , parent + , child + ; + + me._wfnodegroups = fnodeGroups; + me._wcurfiles = files; + + // no error, great + if (!err) { + me._wReadFiles(); + return; + } + + // TODO path.sep + me._wcurpath = me._wcurpath.replace(/\/$/, ''); + + // error? not first run? => directory error + if (!me._wfirstrun) { + // TODO v3.0 (don't noop the next if there are listeners) + me.emit('directoryError', me._wcurpath, { error: err }, noop); + // TODO v3.0 + //me.emit('directoryError', me._wcurpath.replace(/^(.*)\/.*$/, '$1'), { name: me._wcurpath.replace(/^.*\/(.*)/, '$1'), error: err }, noop); + me._wReadFiles(); + return; + } + + // error? first run? => maybe a file, maybe a true error + me._wfirstrun = false; + + // readdir failed (might be a file), try a stat on the parent + parent = me._wcurpath.replace(/^(.*)\/.*$/, '$1'); + fs[me._wStat](parent, function (e, stat) { + + if (stat) { + // success + // now try stat on this as a child of the parent directory + child = me._wcurpath.replace(/^.*\/(.*)$/, '$1'); + me._wcurfiles = [child]; + me._wcurpath = parent; + } else { + // TODO v3.0 + //me.emit('directoryError', me._wcurpath.replace(/^(.*)\/.*$/, '$1'), { name: me._wcurpath.replace(/^.*\/(.*)/, '$1'), error: err }, noop); + // TODO v3.0 (don't noop the next) + // the original readdir error, not the parent stat error + me.emit('nodeError', me._wcurpath, { error: err }, noop); + } + + me._wReadFiles(); + }); + }; + Walker.prototype._wFilter = function () { + var me = this + , exclude + ; + + // Stop directories that contain filter keywords + // from continuing through the walk process + exclude = me._wfilters.some(function (filter) { + if (me._wcurpath.match(filter)) { + return true; + } + }); + + return exclude; + }; + Walker.prototype._wWalkSync = function () { + //console.log('walkSync'); + var err + , files + , me = this + ; + + try { + files = fs.readdirSync(me._wcurpath); + } catch(e) { + err = e; + } + + me._wReaddirHandler(err, files); + }; + Walker.prototype._wWalkAsync = function () { + //console.log('walkAsync'); + var me = this + ; + + // TODO how to remove this anony? + fs.readdir(me._wcurpath, function (err, files) { + me._wReaddirHandler(err, files); + }); + }; + Walker.prototype._wNext = function () { + var me = this + ; + + if (me._paused) { + return; + } + if (me._wq.length) { + me._wcurpath = me._wq.pop(); + while (me._wq.length && me._wFilter()) { + me._wcurpath = me._wq.pop(); + } + if (me._wcurpath && !me._wFilter()) { + me._wWalk(); + } else { + me._wNext(); + } + return; + } + me._wqueue.length -= 1; + if (me._wqueue.length) { + me._wq = me._wqueue[me._wqueue.length - 1]; + return me._wNext(); + } + + // To not break compatibility + //process.nextTick(function () { + me.emit('end'); + //}); + }; + Walker.prototype._wJoinPath = function (v, i, o) { + var me = this + ; + + o[i] = [me._wcurpath, path.sep, v].join(''); + }; + Walker.prototype.pause = function () { + this._paused = true; + }; + Walker.prototype.resume = function () { + this._paused = false; + this._wNext(); + }; + + exports.walk = function (path, opts) { + return new Walker(path, opts, false); + }; + + exports.walkSync = function (path, opts) { + return new Walker(path, opts, true); + }; +}()); diff --git a/pype/premiere/extensions/com.pype.avalon/node_modules/walk/package.json b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/package.json new file mode 100644 index 0000000000..28265c85f6 --- /dev/null +++ b/pype/premiere/extensions/com.pype.avalon/node_modules/walk/package.json @@ -0,0 +1,78 @@ +{ + "_from": "walk", + "_id": "walk@2.3.9", + "_inBundle": false, + "_integrity": "sha1-MbTbZnjyrgHDnqn7hyWpAx5Vins=", + "_location": "/walk", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "walk", + "name": "walk", + "escapedName": "walk", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/walk/-/walk-2.3.9.tgz", + "_shasum": "31b4db6678f2ae01c39ea9fb8725a9031e558a7b", + "_spec": "walk", + "_where": "/Library/Application Support/Adobe/CEP/extensions/ppro/node_modules", + "author": { + "name": "AJ ONeal", + "email": "coolaj86@gmail.com" + }, + "bugs": { + "url": "https://github.com/coolaj86/node-walk/issues" + }, + "bundleDependencies": false, + "contributors": [], + "dependencies": { + "foreachasync": "^3.0.0" + }, + "deprecated": false, + "description": "A node port of python's os.walk", + "devDependencies": {}, + "directories": { + "example": "examples", + "test": "test" + }, + "files": [ + "lib" + ], + "homepage": "https://github.com/coolaj86/node-walk", + "keywords": [ + "util", + "os", + "sys", + "fs", + "walk", + "walkSync" + ], + "lib": ".", + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/mit-license.php" + }, + { + "type": "Apache2", + "url": "http://opensource.org/licenses/apache2.0.php" + } + ], + "main": "./lib/walk.js", + "name": "walk", + "repository": { + "url": "git://github.com/coolaj86/node-walk.git" + }, + "scripts": { + "test": "./test/walk-test.sh" + }, + "url": "http://github.com/coolaj86/node-walk", + "version": "2.3.9" +} diff --git a/pype/premiere/extensions/pype_avalon/payloads/Effect Presets and Custom Items.prfpset b/pype/premiere/extensions/com.pype.avalon/payloads/Effect Presets and Custom Items.prfpset similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/Effect Presets and Custom Items.prfpset rename to pype/premiere/extensions/com.pype.avalon/payloads/Effect Presets and Custom Items.prfpset diff --git a/pype/premiere/extensions/pype_avalon/payloads/PProPanel.mxi b/pype/premiere/extensions/com.pype.avalon/payloads/PProPanel.mxi similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/PProPanel.mxi rename to pype/premiere/extensions/com.pype.avalon/payloads/PProPanel.mxi diff --git a/pype/premiere/extensions/pype_avalon/payloads/PProPanel.sqpreset b/pype/premiere/extensions/com.pype.avalon/payloads/PProPanel.sqpreset similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/PProPanel.sqpreset rename to pype/premiere/extensions/com.pype.avalon/payloads/PProPanel.sqpreset diff --git a/pype/premiere/extensions/pype_avalon/payloads/Registry.png b/pype/premiere/extensions/com.pype.avalon/payloads/Registry.png similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/Registry.png rename to pype/premiere/extensions/com.pype.avalon/payloads/Registry.png diff --git a/pype/premiere/extensions/pype_avalon/payloads/addons.png b/pype/premiere/extensions/com.pype.avalon/payloads/addons.png similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/addons.png rename to pype/premiere/extensions/com.pype.avalon/payloads/addons.png diff --git a/pype/premiere/extensions/pype_avalon/payloads/estk.png b/pype/premiere/extensions/com.pype.avalon/payloads/estk.png similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/estk.png rename to pype/premiere/extensions/com.pype.avalon/payloads/estk.png diff --git a/pype/premiere/extensions/pype_avalon/payloads/example.epr b/pype/premiere/extensions/com.pype.avalon/payloads/example.epr similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/example.epr rename to pype/premiere/extensions/com.pype.avalon/payloads/example.epr diff --git a/pype/premiere/extensions/pype_avalon/payloads/localhost.png b/pype/premiere/extensions/com.pype.avalon/payloads/localhost.png similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/localhost.png rename to pype/premiere/extensions/com.pype.avalon/payloads/localhost.png diff --git a/pype/premiere/extensions/pype_avalon/payloads/onbeforeunload.html b/pype/premiere/extensions/com.pype.avalon/payloads/onbeforeunload.html similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/onbeforeunload.html rename to pype/premiere/extensions/com.pype.avalon/payloads/onbeforeunload.html diff --git a/pype/premiere/extensions/pype_avalon/payloads/sequence_output_options.png b/pype/premiere/extensions/com.pype.avalon/payloads/sequence_output_options.png similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/sequence_output_options.png rename to pype/premiere/extensions/com.pype.avalon/payloads/sequence_output_options.png diff --git a/pype/premiere/extensions/pype_avalon/payloads/test.jpg b/pype/premiere/extensions/com.pype.avalon/payloads/test.jpg similarity index 100% rename from pype/premiere/extensions/pype_avalon/payloads/test.jpg rename to pype/premiere/extensions/com.pype.avalon/payloads/test.jpg diff --git a/pype/premiere/extensions/pype_avalon/PProPanel.jsx b/pype/premiere/extensions/com.pype.avalon/pype_avalon.jsx similarity index 94% rename from pype/premiere/extensions/pype_avalon/PProPanel.jsx rename to pype/premiere/extensions/com.pype.avalon/pype_avalon.jsx index 40256158f5..cdf5586f28 100644 --- a/pype/premiere/extensions/pype_avalon/PProPanel.jsx +++ b/pype/premiere/extensions/com.pype.avalon/pype_avalon.jsx @@ -9,7 +9,7 @@ * accordance with the terms of the Adobe license agreement accompanying * it. If you have received this file from a source other than Adobe, * then your use, modification, or distribution of it requires the prior -* written permission of Adobe and also Pype-Club +* written permission of Adobe. **************************************************************************/ if(typeof($)=='undefined'){ $={}; @@ -22,7 +22,7 @@ $._ext = { $.evalFile(path); } catch (e) {alert("Exception:" + e);} }, - // Evaluate all the files in the given folder + // Evaluate all the files in the given folder evalFiles: function(jsxFolderPath) { var folder = new Folder(jsxFolderPath); if (folder.exists) { diff --git a/pype/premiere/extensions/com.pype.rename/.debug b/pype/premiere/extensions/com.pype.rename/.debug new file mode 100644 index 0000000000..2a0c4079a5 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/.debug @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/pype/premiere/extensions/com.pype.rename/.vscode/launch.json b/pype/premiere/extensions/com.pype.rename/.vscode/launch.json new file mode 100644 index 0000000000..8286fbd804 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "attach", + "name": "Attach to Chrome", + "port": 7777, + "webRoot": "${workspaceRoot}" + } + ] +} \ No newline at end of file diff --git a/pype/premiere/extensions/pype_avalon/CSXS/manifest.xml b/pype/premiere/extensions/com.pype.rename/CSXS/manifest.xml similarity index 78% rename from pype/premiere/extensions/pype_avalon/CSXS/manifest.xml rename to pype/premiere/extensions/com.pype.rename/CSXS/manifest.xml index 34890f75be..18d7d3085b 100644 --- a/pype/premiere/extensions/pype_avalon/CSXS/manifest.xml +++ b/pype/premiere/extensions/com.pype.rename/CSXS/manifest.xml @@ -11,14 +11,14 @@ * accordance with the terms of the Adobe license agreement accompanying * it. If you have received this file from a source other than Adobe, * then your use, modification, or distribution of it requires the prior -* written permission of Adobe. +* written permission of Adobe. **************************************************************************/ ---> - + - + @@ -33,11 +33,11 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - + ./index.html - ./PProPanel.jsx + ./PypeRename.jsx --allow-file-access --allow-file-access-from-files @@ -47,8 +47,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> true - Panel - PProPanel (SDK sample panel) + ModalDialog + Pype Rename 300 diff --git a/pype/premiere/extensions/com.pype.rename/PypeRename.jsx b/pype/premiere/extensions/com.pype.rename/PypeRename.jsx new file mode 100644 index 0000000000..cdf5586f28 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/PypeRename.jsx @@ -0,0 +1,66 @@ +/************************************************************************* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2014 Adobe +* All Rights Reserved. +* +* NOTICE: Adobe permits you to use, modify, and distribute this file in +* accordance with the terms of the Adobe license agreement accompanying +* it. If you have received this file from a source other than Adobe, +* then your use, modification, or distribution of it requires the prior +* written permission of Adobe. +**************************************************************************/ +if(typeof($)=='undefined'){ + $={}; +} + +$._ext = { + //Evaluate a file and catch the exception. + evalFile : function(path) { + try { + $.evalFile(path); + } catch (e) {alert("Exception:" + e);} + }, + // Evaluate all the files in the given folder + evalFiles: function(jsxFolderPath) { + var folder = new Folder(jsxFolderPath); + if (folder.exists) { + var jsxFiles = folder.getFiles("*.jsx"); + for (var i = 0; i < jsxFiles.length; i++) { + var jsxFile = jsxFiles[i]; + $._ext.evalFile(jsxFile); + } + } + }, + // entry-point function to call scripts more easily & reliably + callScript: function(dataStr) { + try { + var dataObj = JSON.parse(decodeURIComponent(dataStr)); + if ( + !dataObj || + !dataObj.namespace || + !dataObj.scriptName || + !dataObj.args + ) { + throw new Error('Did not provide all needed info to callScript!'); + } + // call the specified jsx-function + var result = $[dataObj.namespace][dataObj.scriptName].apply( + null, + dataObj.args + ); + // build the payload-object to return + var payload = { + err: 0, + result: result + }; + return encodeURIComponent(JSON.stringify(payload)); + } catch (err) { + var payload = { + err: err + }; + return encodeURIComponent(JSON.stringify(payload)); + } + } +}; diff --git a/pype/premiere/extensions/com.pype.rename/ReadMe.md b/pype/premiere/extensions/com.pype.rename/ReadMe.md new file mode 100644 index 0000000000..36257b49f5 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/ReadMe.md @@ -0,0 +1,215 @@ +# Create panels for Premiere Pro + +*Last updated October 2018, current released version = Premiere Pro 13.0, also known as "Premiere Pro CC 2019". + +# Premiere Pro 13.0 : API Improvements + +We've added many new capabilities for the 13.0 release. All of these are exercised in the PProPanel sample, [available on GitHub](https://github.com/Adobe-CEP/Samples/tree/master/PProPanel). + +### Get and set footage interpretation + +All aspects of Premiere Pro's footage interpretation are now available via API. Among other workflows, this enables panels to replace a footage reference, while preserving existing interpretation information the user may have already set. + +### Get and set sequence settings + +Previously, it was possible to clone existing sequences, and create sequences from a sequence preset. It is now possible to get and set each individual sequence setting, providing much more granular control over sequences. + +### Detect trackItems which are reversed, have speed adjustments, or are adjustment layers + +This important information was previously unavailable. + +### Open projectItems in the Source monitor + +This allows for sequences, multi-cam sequences, still image sequences and merged clips to be opened in the Source monitor. + +### Create sub-sequences + +Lift/extract sections of existing sequences into new ones, with control over whether or not to adopt the track mapping present in the original. + +### Close open sequences + +Close superfluous/distracting sequences. + +### Consolidate Duplicates via API + +Invoke the same duplicate consolidation functionality available to users. + +# Create panels for Premiere Pro + +Further [relevant information](https://medium.com/adobetech/how-to-create-your-first-adobe-panel-in-6-easy-steps-f8bd4ed5778) is available from the Extensibility team; these items are included here as an overview. + +## 1. Obtain and install these + +- [Creative Cloud](http://creative.adobe.com). Use the Creative Cloud + application to install Premiere Pro CC and other Adobe applications with + which you'll be developing and testing, as well as ExtendScript Toolkit + (available under 'previous versions'). + +- The [CEP Test + Panel](https://github.com/Adobe-CEP/CEP-Resources/tree/master/CEP_8.x/Samples/CEP_HTML_Test_Extension-8.0) + shows the full capabilities of CEP panels. + +- The [PProPanel](https://github.com/Adobe-CEP/Samples/tree/master/PProPanel) + sample project is exhaustive in its exercise of Premiere Pro's ExtendScript + API. + +- The + [ZXPSignCmd](https://github.com/Adobe-CEP/CEP-Resources/tree/master/ZXPSignCMD/4.0.7) + signing utility creates signed .zxp bundles for Add-Ons or direct + distribution. + +- Use the [ExManCmd](https://www.adobeexchange.com/resources/28) command line + utility to test .zxp installation. + +## 2. Enable loading of unsigned panels + +*Note: Premiere Pro 13.0 integrates CEP9, so even if you had unsigned panels +loading before (using CEP7 or CEP8), you'll need to perform this step again, but for key CSXS.9.* + +On Mac, type the following into Terminal, then relaunch Finder (either via +rebooting, or from the Force Quit dialog): + +```html +defaults write /Users//Library/Preferences/com.adobe.CSXS.9.plist PlayerDebugMode 1 +``` + +On Windows, make the following registry entry (a new Key, of type String): + +![Registry image](payloads/Registry.png) + +## 3. Put panel into extensions directory + +Put `/PProPanel` or your own panel's containing directory here, to have Premiere +Pro load it: + +```html +Windows: C:\Program Files (x86)\Common Files\Adobe\CEP\extensions +Mac: /Library/Application Support/Adobe/CEP/extensions +``` + +## 4. Write and test your panel's JavaScript using Chrome debugger + +To enable debugging of panels using Chrome’s developer tools, put a file named +`.debug` into your extension’s folder (as a peer of the `/CSXS` folder). The +contents of the file should resemble the following (and the Extension ID must +match the one in the panel's manifest): + +```xml + + + + + + + + +``` + +When the panel is active, you can debug the panel in your web browser by +browsing to `localhost:7777`, and selecting your panel: + +![Localhost screenshot](payloads/localhost.png) + +Optional diagnostics: Turn on CEP logging. Find CEP logs (distinct from Premiere +Pro's logs) here. Note that Mac Library path is the system's library, not the +user's. Also, note that logging WILL impact performance. + +```html +Windows: %\AppData\Local\Temp\csxs8-PPRO.log +Mac: /Library/Logs/CSXS/csxs8-PPRO.log +``` + +Set logging level in Windows Registry (see above), or MacOS X .plist: + +```html +defaults write /Users//Library/Preferences/com.adobe.CSXS.7.plist LogLevel 6 +``` + +## 5. Create your panel's ExtendScript using ExtendScript Toolkit (ESTK) + +Launch ExtendScript Toolkit, select the correct version of Premiere Pro from the +drop-down menu, then then click the chain link to connect. + +![ESTK Screenshot](payloads/estk.png) + +Once in the session, you can hit breakpoints, and use ExtendScript Toolkit's +Data Browser to view the ExtendScript DOM. + +Here's a [screen video](https://www.dropbox.com/s/lwo8jg0klxkq91s/walkthru.mp4) +showing how to debug panels at both the JavaScript and ExtendScript levels. + +## 6. Package and deploy your panel + +Further [relevant information](https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install) is available from the Extensibility team. + +You can either generate a self-signed certificate (ZXPSignCmd will make them for +you), or get one from a commercial security provider. Here's an example: + +```bash + ./ZXPSignCmd -selfSignedCert US California Adobe "Bruce Bullis" password certificate.p12 +``` + +To sign directory `/PanelDir` with `certificate.p12`, do the following: + +```bash + ./ZXPSignCmd -sign panelDir/ PanelName.zxp certificate.p12 password -tsa http://timestamp.digicert.com/ +``` + +Submit your panel to the [Adobe Add-Ons +site](https://www.adobeexchange.com/producer) for approval, and distribution. +You can also directly supply the .zxp file enterprise customers, and those who +do not connect their systems to the public internet, for installation using +[ExManCmd](https://www.adobeexchange.com/resources/28), the command line version +of Extension Manager. + +If you encounter any issues with the Add-Ons store or ExManCmd, please [contact +the Add-Ons team](mailto:jferman@adobe.com). + +# Previous Updates + +## What was new in 12.1 + +### Get and set the current Project panel selection + +It's now possible for a panel to know which `projectItems` are selected, and to select projectItems as appropriate. + +### Consolidate and Transcode API + +All functionality available from Premiere Pro's Project Manager dialog, is now available to panels. + +### Improved time resolution for trackItems + +We now provide (and accept) time values for track items in ticks, eliminating an opportunity for rounding error. + +### Import and change Motion Graphics templates (.mogrts) + +Panels can now insert .mogrt files into sequences, and change the parameters of those .mogrts as desired. + +### Forcibly replace footage + +It's now possible to force Premiere Pro to update the path to a given `projectItem`, even if Premiere Pro doesn't think such a change is advisable. + +### Identify sequences + +All `projectItems` now have an `isSequence()` method; this eliminates the need to compare a list of 'all project items' against a list of 'all sequences', to determine which `projectItems` are and are not sequences. + +### Set the frame rate for projectItems + +Use the handy new `setOverrideFramerate()`. + +### API Documentation + +While the sample panel should continue to be your first option for working example code, Premiere Pro's ExtendScript API [is documented here](http://ppro.aenhancers.com), to enable developer participation. + + +## What was new in 12.0 + +- We've extended our new, not-in-the-QE-DOM Source monitor object, to close the [front-most](https://github.com/Adobe-CEP/Samples/blob/master/PProPanel/jsx/PPRO/Premiere.jsx#L1465) or [all open clips](https://github.com/Adobe-CEP/Samples/blob/master/PProPanel/jsx/PPRO/Premiere.jsx#L1469). + +- [Change the Label](https://github.com/Adobe-CEP/Samples/blob/master/PProPanel/jsx/PPRO/Premiere.jsx#L1473) assigned to projectItems. + +- Query PPro for the [current insertion bin](https://github.com/Adobe-CEP/Samples/blob/master/PProPanel/jsx/PPRO/Premiere.jsx#L1486), the default target for items imported into the project (but not via drag). *Previously, you could set, but not get, the insertion bin.* + +- [Import Compositions](https://github.com/Adobe-CEP/Samples/blob/master/PProPanel/jsx/PPRO/Premiere.jsx#L1502) by name, from After Effects projects. + +- Open PPro's Events panel to see PProPanel's feedback; I've minimized modal alerts. diff --git a/pype/premiere/extensions/com.pype.rename/css/style.css b/pype/premiere/extensions/com.pype.rename/css/style.css new file mode 100644 index 0000000000..b72c460dec --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/css/style.css @@ -0,0 +1,46 @@ +/************************************************************************* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2014 Adobe +* All Rights Reserved. +* +* NOTICE: Adobe permits you to use, modify, and distribute this file in +* accordance with the terms of the Adobe license agreement accompanying +* it. If you have received this file from a source other than Adobe, +* then your use, modification, or distribution of it requires the prior +* written permission of Adobe. +**************************************************************************/ + +p { + font-family: "LucidaGrande", sans-serif; + text-align:center; +} + +button +{ + font-family: "LucidaGrande", sans-serif; + font-size:12px; + border:1px solid; + height:20px; +} + +input[type=text] +{ + height:12px; +} + +#content { + margin-right:auto; + margin-left:auto; + vertical-align:middle; + width:100%; +} + +#content ul { + padding:0px; +} + +#content ul li { + margin:3px 0px 3px 0px; +} diff --git a/pype/premiere/extensions/pype_avalon/ext.js b/pype/premiere/extensions/com.pype.rename/ext.js similarity index 100% rename from pype/premiere/extensions/pype_avalon/ext.js rename to pype/premiere/extensions/com.pype.rename/ext.js diff --git a/pype/premiere/extensions/com.pype.rename/index.html b/pype/premiere/extensions/com.pype.rename/index.html new file mode 100644 index 0000000000..b172e3bbae --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/index.html @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + Refresh panel +

[uninitialized]

+

[uninitialized]

+

[uninitialized]

+

Proxies enabled for sequence:

+ +
+

New in 13.0!

+
+

+

+

+

+ + + + + + + + + + + + +
+
+ + +
+

System

+
+
+

+

+

+

+ + + + + + + + + + + + +

+

+

+

+
+
+

Import and Create

+
+
+

+

+

+

+ + + + + + + + + + + + +

+

+
Drag and drop import
+

+

+

+

+ +
+
+

Metadata and Project manipulation

+
+
+

+

+

+

+ + + + + + + + +

+ + + + + + + + + + + + + + + +

+

+

+

+

Export

+
+
+

+

+

+

+ + + + + + + + + + + + + + + + + +

+

+

+

+
+ + + + + diff --git a/pype/premiere/extensions/com.pype.rename/jsx/PPRO/PPro_API_Constants.jsx b/pype/premiere/extensions/com.pype.rename/jsx/PPRO/PPro_API_Constants.jsx new file mode 100644 index 0000000000..17524d6968 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/jsx/PPRO/PPro_API_Constants.jsx @@ -0,0 +1,60 @@ +/************************************************************************* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2014 Adobe +* All Rights Reserved. +* +* NOTICE: Adobe permits you to use, modify, and distribute this file in +* accordance with the terms of the Adobe license agreement accompanying +* it. If you have received this file from a source other than Adobe, +* then your use, modification, or distribution of it requires the prior +* written permission of Adobe. +**************************************************************************/ +// time display types + +TIMEDISPLAY_24Timecode = 100; +TIMEDISPLAY_25Timecode = 101; +TIMEDISPLAY_2997DropTimecode = 102; +TIMEDISPLAY_2997NonDropTimecode = 103; +TIMEDISPLAY_30Timecode = 104; +TIMEDISPLAY_50Timecode = 105; +TIMEDISPLAY_5994DropTimecode = 106; +TIMEDISPLAY_5994NonDropTimecode = 107; +TIMEDISPLAY_60Timecode = 108; +TIMEDISPLAY_Frames = 109; +TIMEDISPLAY_23976Timecode = 110; +TIMEDISPLAY_16mmFeetFrames = 111; +TIMEDISPLAY_35mmFeetFrames = 112; +TIMEDISPLAY_48Timecode = 113; +TIMEDISPLAY_AudioSamplesTimecode = 200; +TIMEDISPLAY_AudioMsTimecode = 201; + +// field type constants + +FIELDTYPE_Progressive = 0; +FIELDTYPE_UpperFirst = 1; +FIELDTYPE_LowerFirst = 2; + +// audio channel types + +AUDIOCHANNELTYPE_Mono = 0; +AUDIOCHANNELTYPE_Stereo = 1; +AUDIOCHANNELTYPE_51 = 2; +AUDIOCHANNELTYPE_Multichannel = 3; +AUDIOCHANNELTYPE_4Channel = 4; +AUDIOCHANNELTYPE_8Channel = 5; + +// vr projection type + +VRPROJECTIONTYPE_None = 0; +VRPROJECTIONTYPE_Equirectangular = 1; + +// vr stereoscopic type + +VRSTEREOSCOPICTYPE_Monoscopic = 0; +VRSTEREOSCOPICTYPE_OverUnder = 1; +VRSTEREOSCOPICTYPE_SideBySide = 2; + +NOT_SET = -400000; + diff --git a/pype/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx b/pype/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx new file mode 100644 index 0000000000..5906196b8f --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/jsx/PPRO/Premiere.jsx @@ -0,0 +1,2382 @@ +/************************************************************************* +* ADOBE CONFIDENTIAL +* ___________________ +* +* Copyright 2014 Adobe +* All Rights Reserved. +* +* NOTICE: Adobe permits you to use, modify, and distribute this file in +* accordance with the terms of the Adobe license agreement accompanying +* it. If you have received this file from a source other than Adobe, +* then your use, modification, or distribution of it requires the prior +* written permission of Adobe. +**************************************************************************/ +#include "PPro_API_Constants.jsx" + +$._PPP_={ + + createDeepFolderStructure : function(foldersArray, maxDepth) { + if (typeof foldersArray !== 'object' || foldersArray.length <= 0) { + throw new Error('No valid folders array was provided!'); + } + + // if the first folder already exists, throw error + for (var i = 0; i < app.project.rootItem.children.numItems; i++) { + var curChild = app.project.rootItem.children[i]; + if (curChild.type === ProjectItemType.BIN && curChild.name === foldersArray[0]) { + throw new Error('Folder with name "' + curChild.name + '" already exists!'); + } + } + + // create the deep folder structure + var currentBin = app.project.rootItem.createBin(foldersArray[0]); + for (var m = 1; m < foldersArray.length && m < maxDepth; i++) { + currentBin = currentBin.createBin(foldersArray[i]); + } + }, + + getVersionInfo : function() { + return 'PPro ' + app.version + 'x' + app.build; + }, + + getUserName : function() { + var homeDir = new File('~/'); + var userName = homeDir.displayName; + homeDir.close(); + return userName; + }, + + keepPanelLoaded : function() { + app.setExtensionPersistent("com.pype.RenameDialog", 0); // 0, while testing (to enable rapid reload); 1 for "Never unload me, even when not visible." + }, + + updateGrowingFile : function() { + var numItems = app.project.rootItem.children.numItems; + for (var i = 0; i < numItems; i++){ + var currentItem = app.project.rootItem.children[i]; + if (currentItem){ + currentItem.refreshMedia(); + } + } + }, + + getSep : function() { + if (Folder.fs == 'Macintosh') { + return '/'; + } else { + return '\\'; + } + }, + + saveProject : function() { + app.project.save(); + }, + + exportCurrentFrameAsPNG : function() { + app.enableQE(); + var activeSequence = qe.project.getActiveSequence(); // note: make sure a sequence is active in PPro UI + if (activeSequence) { + // Create a file name based on timecode of frame. + var time = activeSequence.CTI.timecode; // CTI = Current Time Indicator. + var removeThese = /:|;/ig; // Why? Because Windows chokes on colons. + time = time.replace(removeThese, '_'); + var outputPath = new File("~/Desktop"); + var outputFileName = outputPath.fsName + $._PPP_.getSep() + time + '___' + activeSequence.name; + activeSequence.exportFramePNG(time, outputFileName); + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + renameFootage : function() { + var item = app.project.rootItem.children[0]; // assumes the zero-th item in the project is footage. + if (item) { + item.name = item.name + ", updated by PProPanel."; + } else { + $._PPP_.updateEventPanel("No project items found."); + } + }, + + getActiveSequenceName : function() { + if (app.project.activeSequence) { + return app.project.activeSequence.name; + } else { + return "No active sequence."; + } + }, + + projectPanelSelectionChanged : function(projectItems, viewID) { + + var remainingArgs = projectItems.length; + var message = ""; + + if (remainingArgs){ + var message = remainingArgs + " items selected: "; + var view = viewID; + + // Concatenate selected project item names, into message. + for (var i = 0; i < projectItems.length; i++) { + message += projectItems[i].name; + remainingArgs--; + if (remainingArgs > 1) { + message += ', '; + } + if (remainingArgs === 1){ + message += ", and "; + } + if (remainingArgs === 0) { + message += "."; + } + } + } else { + message = '0 items selected.'; + } + app.setSDKEventMessage(message, 'info'); + }, + + registerProjectPanelSelectionChangedFxn : function() { + var success = app.bind("onSourceClipSelectedInProjectPanel", $._PPP_.projectPanelSelectionChanged); + }, + + saveCurrentProjectLayout : function() { + var currentProjPanelDisplay = app.project.getProjectPanelMetadata(); + if (currentProjPanelDisplay){ + var outFileName = 'Previous_Project_Panel_Display_Settings.xml'; + var actualProjectPath = new File(app.project.path); + var projDir = actualProjectPath.parent; + if (actualProjectPath){ + var completeOutputPath = projDir + $._PPP_.getSep() + outFileName; + var outFile = new File(completeOutputPath); + if (outFile){ + outFile.encoding = "UTF8"; + outFile.open("w", "TEXT", "????"); + outFile.write(currentProjPanelDisplay); + $._PPP_.updateEventPanel("Saved layout to next to the project."); + outFile.close(); + } + actualProjectPath.close(); + } + } else { + $._PPP_.updateEventPanel("Could not retrieve current project layout."); + } + }, + + setProjectPanelMeta : function() { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "XML files:*.xml"; + } + var fileToOpen = File.openDialog ( "Choose Project panel layout to open.", + filterString, + false); + if (fileToOpen) { + if (fileToOpen.fsName.indexOf('.xml')){ // We should really be more careful, but hey, it says it's XML! + fileToOpen.encoding = "UTF8"; + fileToOpen.open("r", "TEXT", "????"); + var fileContents = fileToOpen.read(); + if (fileContents){ + var setResult = app.project.setProjectPanelMetadata(fileContents); + if (setResult){ + $._PPP_.updateEventPanel("Could not update layout using " + fileToOpen.filename + "."); + } else { + $._PPP_.updateEventPanel("Updated layout from .xml file."); + } + } + } + } else { + $._PPP_.updateEventPanel("No valid layout file chosen."); + } + }, + + exportSequenceAsPrProj : function() { + var activeSequence = app.project.activeSequence; + if (activeSequence) { + var startTimeOffset = activeSequence.zeroPoint; + var prProjExtension = '.prproj'; + var outputName = activeSequence.name; + var outFolder = Folder.selectDialog(); + + if (outFolder) { + var completeOutputPath = outFolder.fsName + + $._PPP_.getSep() + + outputName + + prProjExtension; + + app.project.activeSequence.exportAsProject(completeOutputPath); + + $._PPP_.updateEventPanel("Exported " + app.project.activeSequence.name + " to " +completeOutputPath + "."); + } else { + $._PPP_.updateEventPanel("Could not find or create output folder."); + } + + // Here's how to import N sequences from a project. + // + // var seqIDsToBeImported = new Array; + // seqIDsToBeImported[0] = ID1; + // ... + // seqIDsToBeImported[N] = IDN; + // + //app.project.importSequences(pathToPrProj, seqIDsToBeImported); + + }else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + createSequenceMarkers : function() { + var activeSequence = app.project.activeSequence; + if (activeSequence) { + var markers = activeSequence.markers; + if (markers) { + var numMarkers = markers.numMarkers; + if (numMarkers > 0) { + var marker_index = 1; + for(var current_marker = markers.getFirstMarker(); + current_marker !== undefined; + current_marker = markers.getNextMarker(current_marker)){ + if (current_marker.name !== "") { + $._PPP_.updateEventPanel( 'Marker ' + marker_index + ' name = ' + current_marker.name + '.'); + } else { + $._PPP_.updateEventPanel( 'Marker ' + marker_index + ' has no name.'); + } + + if (current_marker.end.seconds > 0) { + $._PPP_.updateEventPanel( 'Marker ' + marker_index + ' duration = ' + (current_marker.end.seconds - current_marker.start.seconds) + ' seconds.'); + } else { + $._PPP_.updateEventPanel( 'Marker ' + marker_index + ' has no duration.'); + } + $._PPP_.updateEventPanel('Marker ' + marker_index + ' starts at ' + current_marker.start.seconds + ' seconds.'); + marker_index = marker_index + 1; + } + } + } + + var newCommentMarker = markers.createMarker(12.345); + newCommentMarker.name = 'Marker created by PProPanel.'; + newCommentMarker.comments = 'Here are some comments, inserted by PProPanel.'; + newCommentMarker.end = 15.6789; + + var newWebMarker = markers.createMarker(14.345); + newWebMarker.name = 'Web marker created by PProPanel.'; + newWebMarker.comments = 'Here are some comments, inserted by PProPanel.'; + newWebMarker.end = 17.6789; + newWebMarker.setTypeAsWebLink("http://www.adobe.com", "frame target"); + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + exportFCPXML : function() { + if (app.project.activeSequence) { + var projPath = new File(app.project.path); + var parentDir = projPath.parent; + var outputName = app.project.activeSequence.name; + var xmlExtension = '.xml'; + var outputPath = Folder.selectDialog("Choose the output directory"); + + if (outputPath) { + var completeOutputPath = outputPath.fsName + $._PPP_.getSep() + outputName + xmlExtension; + app.project.activeSequence.exportAsFinalCutProXML(completeOutputPath, 1); // 1 == suppress UI + var info = "Exported FCP XML for " + + app.project.activeSequence.name + + " to " + + completeOutputPath + + "."; + $._PPP_.updateEventPanel(info); + } else { + $._PPP_.updateEventPanel("No output path chosen."); + } + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + openInSource : function() { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "All files:*.*"; + } + var fileToOpen = File.openDialog ( "Choose file to open.", + filterString, + false); + if (fileToOpen) { + app.sourceMonitor.openFilePath(fileToOpen.fsName); + app.sourceMonitor.play(1.73); // playback speed as float, 1.0 = normal speed forward + var position = app.sourceMonitor.getPosition(); // new in 13.0 + $._PPP_.updateEventPanel("Current Source monitor position: " + position.seconds + " seconds."); + fileToOpen.close(); + } else { + $._PPP_.updateEventPanel("No file chosen."); + } + }, + + searchForBinWithName : function (nameToFind) { + // deep-search a folder by name in project + var deepSearchBin = function(inFolder) { + if (inFolder && inFolder.name === nameToFind && inFolder.type === 2) { + return inFolder; + } else { + for (var i = 0; i < inFolder.children.numItems; i++) { + if (inFolder.children[i] && inFolder.children[i].type === 2) { + var foundBin = deepSearchBin(inFolder.children[i]); + if (foundBin) return foundBin; + } + } + } + return undefined; + }; + return deepSearchBin(app.project.rootItem); + }, + + importFiles : function() { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "All files:*.*"; + } + if (app.project) { + var fileOrFilesToImport = File.openDialog ( "Choose files to import", // title + filterString, // filter available files? + true); // allow multiple? + if (fileOrFilesToImport) { + // We have an array of File objects; importFiles() takes an array of paths. + var importThese = []; + if (importThese){ + for (var i = 0; i < fileOrFilesToImport.length; i++) { + importThese[i] = fileOrFilesToImport[i].fsName; + } + app.project.importFiles(importThese, + 1, // suppress warnings + app.project.getInsertionBin(), + 0); // import as numbered stills + } + } else { + $._PPP_.updateEventPanel("No files to import."); + } + } + }, + + muteFun : function() { + if (app.project.activeSequence){ + for (var i = 0; i < app.project.activeSequence.audioTracks.numTracks; i++){ + var currentTrack = app.project.activeSequence.audioTracks[i]; + if (Math.random() > 0.5){ + currentTrack.setMute(!(currentTrack.isMuted())); + } + } + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + disableImportWorkspaceWithProjects : function() { + var prefToModify = 'FE.Prefs.ImportWorkspace'; + var appProperties = app.properties; + + if (appProperties){ + var propertyExists = app.properties.doesPropertyExist(prefToModify); + var propertyIsReadOnly = app.properties.isPropertyReadOnly(prefToModify); + var propertyValue = app.properties.getProperty(prefToModify); + + appProperties.setProperty(prefToModify, false, 1); // optional 3rd param : 0 = non-persistent, 1 = persistent (default) + var safetyCheck = app.properties.getProperty(prefToModify); + if (safetyCheck != propertyValue){ + $._PPP_.updateEventPanel("Changed \'Import Workspaces with Projects\' from " + propertyValue + " to " + safetyCheck + "."); + } + } else { + $._PPP_.updateEventPanel("Properties not found."); + } + }, + + turnOffStartDialog : function (){ + var prefToModify = 'MZ.Prefs.ShowQuickstartDialog'; + var appProperties = app.properties; + if (appProperties){ + var propertyExists = app.properties.doesPropertyExist(prefToModify); + var propertyIsReadOnly = app.properties.isPropertyReadOnly(prefToModify); + var originalValue = app.properties.getProperty(prefToModify); + + appProperties.setProperty(prefToModify, false, 1, 1); // optional 4th param : 0 = non-persistent, 1 = persistent (default) + var safetyCheck = app.properties.getProperty(prefToModify); + if (safetyCheck != originalValue){ + $._PPP_.updateEventPanel("Start dialog now OFF. Enjoy!"); + } else { + $._PPP_.updateEventPanel("Start dialog was already OFF."); + } + } else { + $._PPP_.updateEventPanel("Properties not found."); + } + }, + + replaceMedia : function() { + + // Note: This method of changing paths for projectItems is from the time + // before PPro supported full-res AND proxy paths for each projectItem. + // This can still be used, and will change the hi-res projectItem path, but + // if your panel supports proxy workflows, it should rely instead upon + // projectItem.setProxyPath() instead. + + var firstProjectItem = app.project.rootItem.children[0]; + if (firstProjectItem) { + if (firstProjectItem.canChangeMediaPath()) { + + // NEW in 9.0: setScaleToFrameSize() ensures that for all clips created from this footage, + // auto scale to frame size will be ON, regardless of the current user preference. + // This is important for proxy workflows, to avoid mis-scaling upon replacement. + + // Addendum: This setting will be in effect the NEXT time the projectItem is added to a + // sequence; it will not affect or reinterpret clips from this projectItem, already in + // sequences. + + firstProjectItem.setScaleToFrameSize(); + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "All files:*.*"; + } + var replacementMedia = File.openDialog( "Choose new media file, for " + + firstProjectItem.name, + filterString, // file filter + false); // allow multiple? + + if (replacementMedia) { + var suppressWarnings = true; + firstProjectItem.name = replacementMedia.name + ", formerly known as " + firstProjectItem.name; + firstProjectItem.changeMediaPath(replacementMedia.fsName, suppressWarnings); // new in 12.1 + replacementMedia.close(); + } + } else { + $._PPP_.updateEventPanel("Couldn't change path of " + firstProjectItem.name + "."); + } + } else { + $._PPP_.updateEventPanel("No project items found."); + } + }, + + openProject : function() { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "Premiere Pro project files:*.prproj"; + } + var projToOpen = File.openDialog ( "Choose project:", + filterString, + false); + if ((projToOpen) && projToOpen.exists) { + app.openDocument( projToOpen.fsName, + 1, // suppress 'Convert Project' dialogs? + 1, // suppress 'Locate Files' dialogs? + 1); // suppress warning dialogs? + projToOpen.close(); + } + }, + + exportFramesForMarkers : function (){ + app.enableQE(); + var activeSequence = app.project.activeSequence; + if (activeSequence) { + var markers = activeSequence.markers; + var markerCount = markers.numMarkers; + if (markerCount){ + var firstMarker = markers.getFirstMarker(); + activeSequence.setPlayerPosition(firstMarker.start.ticks); + $._PPP_.exportCurrentFrameAsPNG(); + + var previousMarker = 0; + if (firstMarker){ + for(var i = 0; i < markerCount; i++){ + if (i === 0){ + currentMarker = markers.getNextMarker(firstMarker); + } else { + currentMarker = markers.getNextMarker(previousMarker); + } + if (currentMarker){ + activeSequence.setPlayerPosition(currentMarker.start.ticks); + previousMarker = currentMarker; + $._PPP_.exportCurrentFrameAsPNG(); + } + } + } + } else { + $._PPP_.updateEventPanel("No markers applied to " + activeSequence.name + "."); + } + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + createSequence : function(name) { + var someID = "xyz123"; + var seqName = prompt('Name of sequence?', '<<>>', 'Sequence Naming Prompt'); + app.project.createNewSequence(seqName, someID); + }, + + createSequenceFromPreset : function(presetPath) { + app.enableQE(); + var seqName = prompt('Name of sequence?', '<<>>', 'Sequence Naming Prompt'); + if (seqName) { + qe.project.newSequence(seqName, presetPath); + } + }, + + transcode : function(outputPresetPath) { + app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete); + app.encoder.bind('onEncoderJobError', $._PPP_.onEncoderJobError); + app.encoder.bind('onEncoderJobProgress', $._PPP_.onEncoderJobProgress); + app.encoder.bind('onEncoderJobQueued', $._PPP_.onEncoderJobQueued); + app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled); + + var projRoot = app.project.rootItem.children; + + if (projRoot.numItems){ + var firstProjectItem = app.project.rootItem.children[0]; + if (firstProjectItem){ + + app.encoder.launchEncoder(); // This can take a while; let's get the ball rolling. + + var fileOutputPath = Folder.selectDialog("Choose the output directory"); + if (fileOutputPath){ + var outputName = firstProjectItem.name.search('[.]'); + if (outputName == -1){ + outputName = firstProjectItem.name.length; + } + outFileName = firstProjectItem.name.substr(0, outputName); + outFileName = outFileName.replace('/', '-'); + var completeOutputPath = fileOutputPath.fsName + $._PPP_.getSep() + outFileName + '.mxf'; + var removeFromQueue = true; + var rangeToEncode = app.encoder.ENCODE_IN_TO_OUT; + app.encoder.encodeProjectItem( firstProjectItem, + completeOutputPath, + outputPresetPath, + rangeToEncode, + removeFromQueue); + app.encoder.startBatch(); + } + } else { + $._PPP_.updateEventPanel("No project items found."); + } + } else { + $._PPP_.updateEventPanel("Project is empty."); + } + }, + + transcodeExternal : function (outputPresetPath){ + app.encoder.launchEncoder(); + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "All files:*.*"; + } + var fileToTranscode = File.openDialog ( "Choose file to open.", + filterString, + false); + if (fileToTranscode) { + var fileOutputPath = Folder.selectDialog("Choose the output directory"); + if (fileOutputPath){ + + var srcInPoint = 1.0; // encode start time at 1s (optional--if omitted, encode entire file) + var srcOutPoint = 3.0; // encode stop time at 3s (optional--if omitted, encode entire file) + var removeFromQueue = false; + + var result = app.encoder.encodeFile(fileToTranscode.fsName, + fileOutputPath.fsName, + outputPresetPath, + removeFromQueue, + srcInPoint, + srcOutPoint); + } + } + }, + + render : function(outputPresetPath) { + app.enableQE(); + var activeSequence = qe.project.getActiveSequence(); // we use a QE DOM function, to determine the output extension. + if (activeSequence) { + app.encoder.launchEncoder(); // This can take a while; let's get the ball rolling. + + var timeSecs = activeSequence.CTI.secs; // Just for reference, here's how to access the CTI + var timeFrames = activeSequence.CTI.frames; // (Current Time Indicator), for the active sequence. + var timeTicks = activeSequence.CTI.ticks; + var timeString = activeSequence.CTI.timecode; + + var seqInPoint = app.project.activeSequence.getInPoint(); // new in 9.0 + var seqOutPoint = app.project.activeSequence.getOutPoint(); // new in 9.0 + + var seqInPointAsTime = app.project.activeSequence.getInPointAsTime(); // new in 12.0 + var seqOutPointAsTime = app.project.activeSequence.getOutPointAsTime(); // new in 12.0 + + var projPath = new File(app.project.path); + var outputPath = Folder.selectDialog("Choose the output directory"); + + if ((outputPath) && projPath.exists){ + var outPreset = new File(outputPresetPath); + if (outPreset.exists === true){ + var outputFormatExtension = activeSequence.getExportFileExtension(outPreset.fsName); + if (outputFormatExtension){ + var outputFilename = activeSequence.name + '.' + outputFormatExtension; + + var fullPathToFile = outputPath.fsName + + $._PPP_.getSep() + + activeSequence.name + + "." + + outputFormatExtension; + + var outFileTest = new File(fullPathToFile); + + if (outFileTest.exists){ + var destroyExisting = confirm("A file with that name already exists; overwrite?", false, "Are you sure...?"); + if (destroyExisting){ + outFileTest.remove(); + outFileTest.close(); + } + } + + app.encoder.bind('onEncoderJobComplete', $._PPP_.onEncoderJobComplete); + app.encoder.bind('onEncoderJobError', $._PPP_.onEncoderJobError); + app.encoder.bind('onEncoderJobProgress', $._PPP_.onEncoderJobProgress); + app.encoder.bind('onEncoderJobQueued', $._PPP_.onEncoderJobQueued); + app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled); + + + // use these 0 or 1 settings to disable some/all metadata creation. + + app.encoder.setSidecarXMPEnabled(0); + app.encoder.setEmbeddedXMPEnabled(0); + + /* + + For reference, here's how to export from within PPro (blocking further user interaction). + + var seq = app.project.activeSequence; + + if (seq) { + seq.exportAsMediaDirect(fullPathToFile, + outPreset.fsName, + app.encoder.ENCODE_WORKAREA); + + Bonus: Here's how to compute a sequence's duration, in ticks. 254016000000 ticks/second. + var sequenceDuration = app.project.activeSequence.end - app.project.activeSequence.zeroPoint; + } + + */ + + var jobID = app.encoder.encodeSequence( app.project.activeSequence, + fullPathToFile, + outPreset.fsName, + app.encoder.ENCODE_WORKAREA, + 1); // Remove from queue upon successful completion? + $._PPP_.updateEventPanel('jobID = ' + jobID); + outPreset.close(); + } + } else { + $._PPP_.updateEventPanel("Could not find output preset."); + } + } else { + $._PPP_.updateEventPanel("Could not find/create output path."); + } + projPath.close(); + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + saveProjectCopy : function() { + var sessionCounter = 1; + var originalPath = app.project.path; + var outputPath = Folder.selectDialog("Choose the output directory"); + + if (outputPath) { + var absPath = outputPath.fsName; + var outputName = String(app.project.name); + var array = outputName.split('.', 2); + + outputName = array[0]+ sessionCounter + '.' + array[1]; + sessionCounter++; + + var fullOutPath = absPath + $._PPP_.getSep() + outputName; + + app.project.saveAs(fullOutPath); + + for (var a = 0; a < app.projects.numProjects; a++){ + var currentProject = app.projects[a]; + if (currentProject.path === fullOutPath){ + app.openDocument(originalPath); // Why first? So we don't frighten the user by making PPro's window disappear. :) + currentProject.closeDocument(); + } + } + } else { + $._PPP_.updateEventPanel("No output path chosen."); + } + }, + + mungeXMP : function(){ + var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. + if (projectItem) { + if (ExternalObject.AdobeXMPScript === undefined) { + ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); + } + if (ExternalObject.AdobeXMPScript !== undefined) { // safety-conscious! + + var xmpBlob = projectItem.getXMPMetadata(); + var xmp = new XMPMeta(xmpBlob); + var oldSceneVal = ""; + var oldDMCreatorVal = ""; + + if (xmp.doesPropertyExist(XMPConst.NS_DM, "scene") === true){ + var myScene = xmp.getProperty(XMPConst.NS_DM, "scene"); + oldSceneVal = myScene.value; + } + + if (xmp.doesPropertyExist(XMPConst.NS_DM, "creator") === true){ + var myCreator = xmp.getProperty(XMPConst.NS_DM, "creator"); + oldCreatorVal = myCreator.value; + } + + // Regardless of whether there WAS scene or creator data, set scene and creator data. + + xmp.setProperty(XMPConst.NS_DM, "scene", oldSceneVal + " Added by PProPanel sample!"); + xmp.setProperty(XMPConst.NS_DM, "creator", oldDMCreatorVal + " Added by PProPanel sample!"); + + // That was the NS_DM creator; here's the NS_DC creator. + + var creatorProp = "creator"; + var containsDMCreatorValue = xmp.doesPropertyExist(XMPConst.NS_DC, creatorProp); + var numCreatorValuesPresent = xmp.countArrayItems(XMPConst.NS_DC, creatorProp); + var CreatorsSeparatedBy4PoundSigns = ""; + + if(numCreatorValuesPresent > 0) { + for (var z = 0; z < numCreatorValuesPresent; z++){ + CreatorsSeparatedBy4PoundSigns = CreatorsSeparatedBy4PoundSigns + xmp.getArrayItem(XMPConst.NS_DC, creatorProp, z + 1); + CreatorsSeparatedBy4PoundSigns = CreatorsSeparatedBy4PoundSigns + "####"; + } + $._PPP_.updateEventPanel(CreatorsSeparatedBy4PoundSigns); + + if (confirm("Replace previous?", false, "Replace existing Creator?")) { + xmp.deleteProperty(XMPConst.NS_DC, "creator"); + } + xmp.appendArrayItem(XMPConst.NS_DC, // If no values exist, appendArrayItem will create a value. + creatorProp, + numCreatorValuesPresent + " creator values were already present.", + null, + XMPConst.ARRAY_IS_ORDERED); + + } else { + + xmp.appendArrayItem(XMPConst.NS_DC, + creatorProp, + "PProPanel wrote the first value into NS_DC creator field.", + null, + XMPConst.ARRAY_IS_ORDERED); + } + var xmpAsString = xmp.serialize(); // either way, serialize and write XMP. + projectItem.setXMPMetadata(xmpAsString); + } + } else { + $._PPP_.updateEventPanel("Project item required."); + } + }, + + getProductionByName : function(nameToGet) { + var production; + for (var i = 0; i < productionList.numProductions; i++) { + var currentProduction = productionList[i]; + + if (currentProduction.name == nameToGet) { + production = currentProduction; + } + } + return production; + }, + + pokeAnywhere : function() { + var token = app.anywhere.getAuthenticationToken(); + var productionList = app.anywhere.listProductions(); + var isProductionOpen = app.anywhere.isProductionOpen(); + if (isProductionOpen === true) { + var sessionURL = app.anywhere.getCurrentEditingSessionURL(); + var selectionURL = app.anywhere.getCurrentEditingSessionSelectionURL(); + var activeSequenceURL = app.anywhere.getCurrentEditingSessionActiveSequenceURL(); + + var theOneIAskedFor = $._PPP_.getProductionByName("test"); + + if (theOneIAskedFor) { + var out = theOneIAskedFor.name + ", " + theOneIAskedFor.description; + $._PPP_.updateEventPanel("Found: " + out); // todo: put useful code here. + } + } else { + $._PPP_.updateEventPanel("No Production open."); + } + }, + + dumpOMF : function() { + var activeSequence = app.project.activeSequence; + if (activeSequence) { + var outputPath = Folder.selectDialog("Choose the output directory"); + if (outputPath){ + var absPath = outputPath.fsName; + var outputName = String(activeSequence.name) + '.omf'; + var fullOutPathWithName = absPath + $._PPP_.getSep() + outputName; + + app.project.exportOMF( app.project.activeSequence, // sequence + fullOutPathWithName, // output file path + 'OMFTitle', // OMF title + 48000, // sample rate (48000 or 96000) + 16, // bits per sample (16 or 24) + 1, // audio encapsulated flag (1 : yes or 0 : no) + 0, // audio file format (0 : AIFF or 1 : WAV) + 0, // trim audio files (0 : no or 1 : yes) + 0, // handle frames (if trim is 1, handle frames from 0 to 1000) + 0); // include pan flag (0 : no or 1 : yes) + } + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + addClipMarkers : function () { + if (app.project.rootItem.children.numItems > 0){ + var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. + if (projectItem) { + if (projectItem.type == ProjectItemType.CLIP || projectItem.type == ProjectItemType.FILE) { + + markers = projectItem.getMarkers(); + + if (markers) { + var num_markers = markers.numMarkers; + var new_marker = markers.createMarker(12.345); + var guid = new_marker.guid; // new in 11.1 + + new_marker.name = 'Marker created by PProPanel.'; + new_marker.comments = 'Here are some comments, inserted by PProPanel.'; + new_marker.end = 15.6789; + + //default marker type == comment. To change marker type, call one of these: + + // new_marker.setTypeAsChapter(); + // new_marker.setTypeAsWebLink(); + // new_marker.setTypeAsSegmentation(); + // new_marker.setTypeAsComment(); + } + } else { + $._PPP_.updateEventPanel("Can only add markers to footage items."); + } + } else { + $._PPP_.updateEventPanel("Could not find first projectItem."); + } + } else { + $._PPP_.updateEventPanel("Project is empty."); + } + }, + + modifyProjectMetadata : function () { + var kPProPrivateProjectMetadataURI = "http://ns.adobe.com/premierePrivateProjectMetaData/1.0/"; + + var namefield = "Column.Intrinsic.Name"; + var tapename = "Column.Intrinsic.TapeName"; + var desc = "Column.PropertyText.Description"; + var logNote = "Column.Intrinsic.LogNote"; + var newField = "ExampleFieldName"; + + if (app.isDocumentOpen()) { + var projectItem = app.project.rootItem.children[0]; // just grabs first projectItem. + if (projectItem) { + if (ExternalObject.AdobeXMPScript === undefined) { + ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); + } + if (ExternalObject.AdobeXMPScript !== undefined) { // safety-conscious! + var projectMetadata = projectItem.getProjectMetadata(); + var successfullyAdded = app.project.addPropertyToProjectMetadataSchema(newField, "ExampleFieldLabel", 2); + + var xmp = new XMPMeta(projectMetadata); + var obj = xmp.dumpObject(); + + // var aliases = xmp.dumpAliases(); + + var namespaces = XMPMeta.dumpNamespaces(); + var found_name = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, namefield); + var found_tapename = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, tapename); + var found_desc = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, desc); + var found_custom = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, newField); + var foundLogNote = xmp.doesPropertyExist(kPProPrivateProjectMetadataURI, logNote); + var oldLogValue = ""; + var appendThis = "This log note inserted by PProPanel."; + var appendTextWasActuallyNew = false; + + if(foundLogNote){ + var oldLogNote = xmp.getProperty(kPProPrivateProjectMetadataURI, logNote); + if (oldLogNote){ + oldLogValue = oldLogNote.value; + } + } + + xmp.setProperty(kPProPrivateProjectMetadataURI, tapename, "***TAPENAME***"); + xmp.setProperty(kPProPrivateProjectMetadataURI, desc, "***DESCRIPTION***"); + xmp.setProperty(kPProPrivateProjectMetadataURI, namefield, "***NEWNAME***"); + xmp.setProperty(kPProPrivateProjectMetadataURI, newField, "PProPanel set this, using addPropertyToProjectMetadataSchema()."); + + + var array = []; + array[0] = tapename; + array[1] = desc; + array[2] = namefield; + array[3] = newField; + + var concatenatedLogNotes = ""; + + if (oldLogValue != appendThis){ // if that value is not exactly what we were going to add + if (oldLogValue.length > 0){ // if we have a valid value + concatenatedLogNotes += "Previous log notes: " + oldLogValue + " |||| "; + } + concatenatedLogNotes += appendThis; + xmp.setProperty(kPProPrivateProjectMetadataURI, logNote, concatenatedLogNotes); + array[4] = logNote; + } + + var str = xmp.serialize(); + projectItem.setProjectMetadata(str, array); + + // test: is it in there? + + var newblob = projectItem.getProjectMetadata(); + var newXMP = new XMPMeta(newblob); + var foundYet = newXMP.doesPropertyExist(kPProPrivateProjectMetadataURI, newField); + + if (foundYet){ + $._PPP_.updateEventPanel("PProPanel successfully added a field to the project metadata schema, and set a value for it."); + } + } + } else { + $._PPP_.updateEventPanel("No project items found."); + } + } + }, + + updatePAR : function() { + var item = app.project.rootItem.children[0]; + if (item) { + if ((item.type == ProjectItemType.FILE) || (item.type == ProjectItemType.CLIP)){ + // If there is an item, and it's either a clip or file... + item.setOverridePixelAspectRatio(185, 100); // anamorphic is BACK! ;) + } else { + $._PPP_.updateEventPanel('You cannot override the PAR of bins or sequences.'); + } + } else { + $._PPP_.updateEventPanel("No project items found."); + } + }, + + getnumAEProjectItems : function() { + var bt = new BridgeTalk(); + bt.target = 'aftereffects'; + bt.body = //'$._PPP_.updateEventPanel("Items in AE project: " + app.project.rootFolder.numItems);app.quit();'; + 'alert("Items in AE project: " + app.project.rootFolder.numItems);app.quit();'; + bt.send(); + }, + + updateEventPanel : function(message) { + app.setSDKEventMessage(message, 'info'); + //app.setSDKEventMessage('Here is some information.', 'info'); + //app.setSDKEventMessage('Here is a warning.', 'warning'); + //app.setSDKEventMessage('Here is an error.', 'error'); // Very annoying; use sparingly. + }, + + walkAllBinsForFootage : function(parentItem, outPath){ + for (var j = 0; j < parentItem.children.numItems; j++){ + var currentChild = parentItem.children[j]; + if (currentChild){ + if (currentChild.type == ProjectItemType.BIN){ + $._PPP_.walkAllBinsForFootage(currentChild, outPath); // warning; recursion! + } else { + $._PPP_.dumpProjectItemXMP(currentChild, outPath); + } + } + } + }, + + searchBinForProjItemByName : function(i, containingBin, nameToFind){ + for (var j = i; j < containingBin.children.numItems; j++){ + var currentChild = containingBin.children[j]; + if (currentChild){ + if (currentChild.type == ProjectItemType.BIN){ + return $._PPP_.searchBinForProjItemByName(j, currentChild, nameToFind); // warning; recursion! + } else { + if (currentChild.name == nameToFind){ + return currentChild; + } else { + currentChild = currentItem.children[j+1]; + if (currentChild){ + return $._PPP_.searchBinForProjItemByName(0, currentChild, nameToFind); + } + } + } + } + } + }, + + dumpProjectItemXMP : function (projectItem, outPath) { + var xmpBlob = projectItem.getXMPMetadata(); + var outFileName = projectItem.name + '.xmp'; + var completeOutputPath = outPath + $._PPP_.getSep() + outFileName; + var outFile = new File(completeOutputPath); + + var isThisASequence = projectItem.isSequence(); + + if (outFile){ + outFile.encoding = "UTF8"; + outFile.open("w", "TEXT", "????"); + outFile.write(xmpBlob.toString()); + outFile.close(); + } + }, + + addSubClip : function() { + var startTime = new Time; + startTime.seconds = 0.0; + var endTime = new Time; + endTime.seconds = 3.21; + var hasHardBoundaries = 0; + var sessionCounter = 1; + var takeVideo = 1; // optional, defaults to 1 + var takeAudio = 1; // optional, defaults to 1 + var projectItem = app.project.rootItem.children[0]; // just grabs the first item + if (projectItem) { + if ((projectItem.type == ProjectItemType.CLIP) || (projectItem.type == ProjectItemType.FILE)) { + var newSubClipName = prompt('Name of subclip?', projectItem.name + '_' + sessionCounter, 'Name your subclip'); + + var newSubClip = projectItem.createSubClip(newSubClipName, + startTime, + endTime, + hasHardBoundaries, + takeVideo, + takeAudio); + + if (newSubClip){ + newSubClip.setStartTime(12.345); + } + } else { + $._PPP_.updateEventPanel("Could not sub-clip " + projectItem.name + "."); + } + } else { + $._PPP_.updateEventPanel("No project item found."); + } + }, + + dumpXMPFromAllProjectItems : function() { + var numItemsInRoot = app.project.rootItem.children.numItems; + if (numItemsInRoot > 0) { + var outPath = Folder.selectDialog("Choose the output directory"); + if (outPath) { + for (var i = 0; i < numItemsInRoot; i++){ + var currentItem = app.project.rootItem.children[i]; + if (currentItem){ + if (currentItem.type == ProjectItemType.BIN){ + $._PPP_.walkAllBinsForFootage(currentItem, outPath.fsName); + } else { + $._PPP_.dumpProjectItemXMP(currentItem, outPath.fsName); + } + } + } + } + } else { + $._PPP_.updateEventPanel("No project items found."); + } + }, + + exportAAF : function() { + var sessionCounter = 1; + if (app.project.activeSequence){ + var outputPath = Folder.selectDialog("Choose the output directory"); + if (outputPath) { + var absPath = outputPath.fsName; + var outputName = String(app.project.name); + var array = outputName.split('.', 2); + outputName = array[0]+ sessionCounter + '.' + array[1]; + + sessionCounter++; + var fullOutPath = absPath + $._PPP_.getSep() + outputName + '.aaf'; + //var optionalPathToOutputPreset = null; New in 11.0.0, you can specify an output preset. + + app.project.exportAAF( app.project.activeSequence, // which sequence + fullOutPath, // output path + 1, // mix down video? + 0, // explode to mono? + 96000, // sample rate + 16, // bits per sample + 0, // embed audio? + 0, // audio file format? 0 = aiff, 1 = wav + 0, // trim sources? + 0/*, // number of 'handle' frames + optionalPathToOutputPreset*/); // optional; .epr file to use + } else { + $._PPP_.updateEventPanel("Couldn't create AAF output."); + } + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + setScratchDisk : function (){ + var scratchPath = Folder.selectDialog("Choose new scratch disk directory"); + if ((scratchPath) && scratchPath.exists) { + app.setScratchDiskPath(scratchPath.fsName, ScratchDiskType.FirstAutoSaveFolder); // see ScratchDiskType object, in ESTK. + } + }, + + getProjectProxySetting : function() { + var returnVal = ""; + if (app.project){ + var returnVal = "No sequence detected in " + app.project.name + "."; + if (app.getEnableProxies()) { + returnVal = 'true'; + } else { + returnVal = 'false'; + } + } else { + returnVal = "No project available."; + } + return returnVal; + }, + + toggleProxyState : function() { + var update = "Proxies for " + app.project.name + " turned "; + if (app.getEnableProxies()) { + app.setEnableProxies(0); + update = update + "OFF."; + app.setSDKEventMessage(update, 'info'); + } else { + app.setEnableProxies(1); + update = update + "ON."; + app.setSDKEventMessage(update, 'info'); + } + }, + + setProxiesON : function () { + var firstProjectItem = app.project.rootItem.children[0]; + if (firstProjectItem) { + if (firstProjectItem.canProxy()){ + var shouldAttachProxy = true; + if (firstProjectItem.hasProxy()) { + shouldAttachProxy = confirm(firstProjectItem.name + " already has an assigned proxy. Re-assign anyway?", false, "Are you sure...?"); + } + if (shouldAttachProxy) { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "All files:*.*"; + } + var proxyPath = File.openDialog( "Choose proxy for " + firstProjectItem.name + ":", + filterString, + false); + if (proxyPath.exists){ + firstProjectItem.attachProxy(proxyPath.fsName, 0); + } else { + $._PPP_.updateEventPanel("Could not attach proxy from " + proxyPath + "."); + } + } + } else { + $._PPP_.updateEventPanel("Cannot attach a proxy to " + firstProjectItem.name + "."); + } + } else { + $._PPP_.updateEventPanel("No project item available."); + } + }, + + clearCache : function () { + app.enableQE(); + MediaType = {}; + + // Magical constants from Premiere Pro's internal automation. + + MediaType.VIDEO = "228CDA18-3625-4d2d-951E-348879E4ED93"; + MediaType.AUDIO = "80B8E3D5-6DCA-4195-AEFB-CB5F407AB009"; + MediaType.ANY = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"; + qe.project.deletePreviewFiles(MediaType.ANY); + $._PPP_.updateEventPanel("All video and audio preview files deleted."); + }, + + randomizeSequenceSelection : function (){ + var sequence = app.project.activeSequence; + + if (sequence){ + var trackGroups = [ sequence.audioTracks, sequence.videoTracks ]; + var trackGroupNames = [ "audioTracks", "videoTracks" ]; + var updateUI = true; + var before; + + for(var gi = 0; gi<2; gi++) { + $._PPP_.updateEventPanel(trackGroupNames[gi]); + group = trackGroups[gi]; + for(var ti=0; ti" : clip.projectItem.name); + before = clip.isSelected(); + + // randomly select clips + clip.setSelected((Math.random() > 0.5), updateUI); + + if (clip.isAdjustmentLayer()){ // new in 13.0 + $._PPP_.updateEventPanel("Clip named \"" + clip.name + "\" is an adjustment layer."); + } + + // Note; there's no good place to exercise this code yet, but + // I wanted to provide example usage. + + var allClipsInThisSequenceFromSameSource = clip.getLinkedItems(); + + if (allClipsInThisSequenceFromSameSource){ + $._PPP_.updateEventPanel("Found " + allClipsInThisSequenceFromSameSource.numItems + " clips from " + clip.projectItem.name + ", in this sequence."); + } + beforeSelected = before ? "Y" : "N"; + afterSelected = clip.selected ? "Y" : "N"; + $._PPP_.updateEventPanel("clip : " + ci + " " + name + " " + beforeSelected + " -> " + afterSelected); + } + + for(var tni=0; tni 0.5), updateUI); + + beforeSelected = before ? "Y" : "N"; + afterSelected = transition.selected ? "Y" : "N"; + + $._PPP_.updateEventPanel('transition: ' + tni + " " + beforeSelected + " -> " + afterSelected); + } + } + } + } else { + $._PPP_.updateEventPanel("no active sequence."); + } + }, + + // Define a couple of callback functions, for AME to use during render. + + onEncoderJobComplete : function (jobID, outputFilePath) { + var eoName; + + if (Folder.fs == 'Macintosh') { + eoName = "PlugPlugExternalObject"; + } else { + eoName = "PlugPlugExternalObject.dll"; + } + + var suffixAddedByPPro = '_1'; // You should really test for any suffix. + var withoutExtension = outputFilePath.slice(0,-4); // trusting 3 char extension + var lastIndex = outputFilePath.lastIndexOf("."); + var extension = outputFilePath.substr(lastIndex + 1); + + if (outputFilePath.indexOf(suffixAddedByPPro)){ + $._PPP_.updateEventPanel(" Output filename was changed: the output preset name may have been added, or there may have been an existing file with that name. This would be a good place to deal with such occurrences."); + } + + var mylib = new ExternalObject('lib:' + eoName); + var eventObj = new CSXSEvent(); + + eventObj.type = "com.adobe.csxs.events.PProPanelRenderEvent"; + eventObj.data = "Rendered Job " + jobID + ", to " + outputFilePath + "."; + + eventObj.dispatch(); + }, + + onEncoderJobError : function (jobID, errorMessage) { + var eoName; + + if (Folder.fs === 'Macintosh') { + eoName = "PlugPlugExternalObject"; + } else { + eoName = "PlugPlugExternalObject.dll"; + } + + var mylib = new ExternalObject('lib:' + eoName); + var eventObj = new CSXSEvent(); + + eventObj.type = "com.adobe.csxs.events.PProPanelRenderEvent"; + eventObj.data = "Job " + jobID + " failed, due to " + errorMessage + "."; + eventObj.dispatch(); + }, + + onEncoderJobProgress : function (jobID, progress) { + $._PPP_.updateEventPanel('onEncoderJobProgress called. jobID = ' + jobID + '. progress = ' + progress + '.'); + }, + + onEncoderJobQueued : function (jobID) { + app.encoder.startBatch(); + }, + + onEncoderJobCanceled : function (jobID) { + $._PPP_.updateEventPanel('OnEncoderJobCanceled called. jobID = ' + jobID + '.'); + }, + + onPlayWithKeyframes : function () { + var seq = app.project.activeSequence; + if (seq) { + var firstVideoTrack = seq.videoTracks[0]; + if (firstVideoTrack){ + var firstClip = firstVideoTrack.clips[0]; + if (firstClip){ + var clipComponents = firstClip.components; + if (clipComponents){ + for (var i = 0; i < clipComponents.numItems; ++i){ + $._PPP_.updateEventPanel('component ' + i + ' = ' + clipComponents[i].matchName + ' : ' + clipComponents[i].displayName); + } + if (clipComponents.numItems > 2){ + + // 0 = clip + // 1 = Opacity + // N effects, then... + // Shape layer (new in 12.0) + + var blur = clipComponents[2]; // Assume Gaussian Blur is the first effect applied to the clip. + if (blur){ + var blurProps = blur.properties; + if (blurProps){ + for( var j = 0; j < blurProps.numItems; ++j){ + $._PPP_.updateEventPanel('param ' + j + ' = ' + blurProps[j].displayName); + } + var blurriness = blurProps[0]; + if (blurriness){ + if (!blurriness.isTimeVarying()){ + blurriness.setTimeVarying(true); + } + for(var k = 0; k < 20; ++k){ + updateUI = (k==9); // Decide how often to update PPro's UI + blurriness.addKey(k); + var blurVal = Math.sin(3.14159*i/5)*20+25; + blurriness.setValueAtKey(k, blurVal, updateUI); + } + } + var repeatEdgePixels = blurProps[2]; + if (repeatEdgePixels){ + if (!repeatEdgePixels.getValue()){ + updateUI = true; + repeatEdgePixels.setValue(true, updateUI); + } + } + // look for keyframe nearest to 4s with 1/10 second tolerance + var keyFrameTime = blurriness.findNearestKey(4.0, 0.1); + if (keyFrameTime !== undefined){ + $._PPP_.updateEventPanel('Found keyframe = ' + keyFrameTime.seconds); + } else { + $._PPP_.updateEventPanel('Keyframe not found.'); + } + + // scan keyframes, forward + + keyFrameTime = blurriness.findNearestKey(0.0, 0.1); + var lastKeyFrameTime = keyFrameTime; + while(keyFrameTime !== undefined){ + $._PPP_.updateEventPanel('keyframe @ ' + keyFrameTime.seconds); + lastKeyFrameTime = keyFrameTime; + keyFrameTime = blurriness.findNextKey(keyFrameTime); + } + + // scan keyframes, backward + keyFrameTime = lastKeyFrameTime; + while(keyFrameTime !== undefined){ + $._PPP_.updateEventPanel('keyframe @ ' + keyFrameTime.seconds); + lastKeyFrameTime = keyFrameTime; + keyFrameTime = blurriness.findPreviousKey(keyFrameTime); + } + + // get all keyframes + + var blurKeyframesArray = blurriness.getKeys(); + if (blurKeyframesArray){ + $._PPP_.updateEventPanel(blurKeyframesArray.length + ' keyframes found'); + } + + // remove keyframe at 19s + blurriness.removeKey(19); + + // remove keyframes in range from 0s to 5s + var shouldUpdateUI = true; + blurriness.removeKeyRange(0,5, shouldUpdateUI); + } + + } else { + $._PPP_.updateEventPanel("Please apply the Gaussian Blur effect to the first clip in the first video track of the active sequence."); + } + } + } + } + } + } else { + $._PPP_.updateEventPanel("no active sequence."); + } + }, + + extractFileNameFromPath : function (fullPath){ + var lastDot = fullPath.lastIndexOf("."); + var lastSep = fullPath.lastIndexOf("/"); + + if (lastDot > -1){ + return fullPath.substr( (lastSep +1), (fullPath.length - (lastDot + 1))); + } else { + return fullPath; + } + }, + + onProxyTranscodeJobComplete : function (jobID, outputFilePath) { + var suffixAddedByPPro = '_1'; // You should really test for any suffix. + var withoutExtension = outputFilePath.slice(0,-4); // trusting 3 char extension + var lastIndex = outputFilePath.lastIndexOf("."); + var extension = outputFilePath.substr(lastIndex + 1); + + var wrapper = []; + wrapper[0] = outputFilePath; + + var nameToFind = 'Proxies generated by PProPanel'; + var targetBin = $._PPP_.getPPPInsertionBin(); + if (targetBin){ + app.project.importFiles(wrapper); + } + }, + + onProxyTranscodeJobError : function (jobID, errorMessage) { + $._PPP_.updateEventPanel(errorMessage); + }, + + onProxyTranscodeJobQueued : function (jobID) { + app.encoder.startBatch(); + }, + + ingestFiles : function(outputPresetPath) { + app.encoder.bind('onEncoderJobComplete', $._PPP_.onProxyTranscodeJobComplete); + app.encoder.bind('onEncoderJobError', $._PPP_.onProxyTranscodeJobError); + app.encoder.bind('onEncoderJobQueued', $._PPP_.onProxyTranscodeJobQueued); + app.encoder.bind('onEncoderJobCanceled', $._PPP_.onEncoderJobCanceled); + + if (app.project) { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "All files:*.*"; + } + var fileOrFilesToImport = File.openDialog( "Choose full resolution files to import", // title + filterString, // filter available files? + true); // allow multiple? + if (fileOrFilesToImport) { + var nameToFind = 'Proxies generated by PProPanel'; + var targetBin = $._PPP_.searchForBinWithName(nameToFind); + if (targetBin === 0) { + // If panel can't find the target bin, it creates it. + app.project.rootItem.createBin(nameToFind); + targetBin = $._PPP_.searchForBinWithName(nameToFind); + } + if (targetBin){ + targetBin.select(); + var importThese = []; // We have an array of File objects; importFiles() takes an array of paths. + if (importThese){ + for (var i = 0; i < fileOrFilesToImport.length; i++) { + importThese[i] = fileOrFilesToImport[i].fsName; + var justFileName = extractFileNameFromPath(importThese[i]); + var suffix = '_PROXY.mp4'; + var containingPath = fileOrFilesToImport[i].parent.fsName; + var completeProxyPath = containingPath + $._PPP_.getSep() + justFileName + suffix; + + var jobID = app.encoder.encodeFile(fileOrFilesToImport[i].fsName, + completeProxyPath, + outputPresetPath, + 0); + } + + app.project.importFiles(importThese, + 1, // suppress warnings + targetBin, + 0); // import as numbered stills + } + } else { + $._PPP_.updateEventPanel("Could not find or create target bin."); + } + } else { + $._PPP_.updateEventPanel("No files to import."); + } + } else { + $._PPP_.updateEventPanel("No project found."); + } + }, + + insertOrAppend : function() { + var seq = app.project.activeSequence; + if (seq){ + var first = app.project.rootItem.children[0]; + if (first){ + var numVTracks = seq.videoTracks.numTracks; + var targetVTrack = seq.videoTracks[(numVTracks - 1)]; + if (targetVTrack){ + // If there are already clips in this track, + // append this one to the end. Otherwise, + // insert at start time. + + if (targetVTrack.clips.numItems > 0){ + var lastClip = targetVTrack.clips[(targetVTrack.clips.numItems - 1)]; + if (lastClip){ + targetVTrack.insertClip(first, lastClip.end.seconds); + } + }else { + targetVTrack.insertClip(first, '00;00;00;00'); + } + } else { + $._PPP_.updateEventPanel("Could not find first video track."); + } + } else { + $._PPP_.updateEventPanel("Couldn't locate first projectItem."); + } + } else { + $._PPP_.updateEventPanel("no active sequence."); + } + }, + + overWrite : function() { + var seq = app.project.activeSequence; + if (seq){ + var first = app.project.rootItem.children[0]; + if (first) { + var vTrack1 = seq.videoTracks[0]; + if (vTrack1){ + var now = seq.getPlayerPosition(); + vTrack1.overwriteClip(first, now.seconds); + } else { + $._PPP_.updateEventPanel("Could not find first video track."); + } + } else { + $._PPP_.updateEventPanel("Couldn't locate first projectItem."); + } + } else { + $._PPP_.updateEventPanel("no active sequence."); + } + }, + + closeFrontSourceClip : function() { + app.sourceMonitor.closeClip(); + }, + + closeAllClipsInSourceMonitor : function() { + app.sourceMonitor.closeAllClips(); + }, + + changeLabel : function () { + var first = app.project.rootItem.children[0]; + if (first){ + var currentLabel = first.getColorLabel(); + var newLabel = currentLabel + 1; // 4 = Cerulean. 0 = Violet, 15 = Yellow. + if (newLabel > 15){ + newLabel = newLabel - 16; + } + app.setSDKEventMessage("Previous Label color = " + currentLabel + ".", 'info'); + first.setColorLabel(newLabel); + app.setSDKEventMessage("New Label color = " + newLabel + ".", 'info'); + } else { + $._PPP_.updateEventPanel("Couldn't locate first projectItem."); + } + }, + + getPPPInsertionBin : function () { + var nameToFind = "Here's where PProPanel puts things."; + + var targetBin = $._PPP_.searchForBinWithName(nameToFind); + + if (targetBin === undefined) { + // If panel can't find the target bin, it creates it. + app.project.rootItem.createBin(nameToFind); + targetBin = $._PPP_.searchForBinWithName(nameToFind); + } + if (targetBin) { + targetBin.select(); + return targetBin; + } + }, + + importComps : function () { + var targetBin = $._PPP_.getPPPInsertionBin(); + if (targetBin){ + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "All files:*.*"; + } + compNamesToImport = []; + + var aepToImport = File.openDialog ( "Choose After Effects project", // title + filterString, // filter available files? + false); // allow multiple? + if (aepToImport) { + var importAll = confirm("Import all compositions in project?", false, "Import all?"); + if (importAll){ + var result = app.project.importAllAEComps(aepToImport.fsName, targetBin); + } else { + var compName = prompt( 'Name of composition to import?', + '', + 'Which Comp to import'); + if (compName){ + compNamesToImport[0] = compName; + var importAECompResult = app.project.importAEComps(aepToImport.fsName, compNamesToImport, targetBin); + } else { + $._PPP_.updateEventPanel("Could not find Composition."); + } + } + } else { + $._PPP_.updateEventPanel("Could not open project."); + } + } else { + $._PPP_.updateEventPanel("Could not find or create target bin."); + } + }, + + consolidateProject : function () { + var pmo = app.projectManager.options; + + if (app.project.sequences.length){ + if (pmo) { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "Output Presets:*.epr"; + } + + var outFolder = Folder.selectDialog("Choose output directory."); + if (outFolder) { + + var presetPath = ""; + var useSpecificPreset = confirm("Would you like to select an output preset?", false, "Are you sure...?"); + if (useSpecificPreset){ + var useThisEPR = File.openDialog ( "Choose output preset (.epr file)", // title + filterString, // filter available files? + false); // allow multiple? + + if (useThisEPR){ + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; + pmo.encoderPresetFilePath = useThisEPR.fsName; + } + } else { + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; + } + + var processAllSequences = confirm("Process all sequences? No = just the first sequence found.", true, "Process all?"); + + if (processAllSequences){ + pmo.includeAllSequences = true; + } else { + pmo.includeAllSequences = false; + pmo.affectedSequences = [app.project.sequences[0]]; + } + + pmo.clipTransferOption = pmo.CLIP_TRANSFER_TRANSCODE; + pmo.convertAECompsToClips = false; + pmo.convertSyntheticsToClips = false; + pmo.copyToPreventAlphaLoss = false; + pmo.destinationPath = outFolder.fsName; + pmo.excludeUnused = false; + pmo.handleFrameCount = 0; + pmo.includeConformedAudio = true; + pmo.includePreviews = true; + pmo.renameMedia = false; + + var result = app.projectManager.process(app.project); + var errorList = app.projectManager.errors; + + if(errorList.length){ + for (var k = 0; k < errorList.length; k++){ + $._PPP_.updateEventPanel(errorList[k][1]); + } + } else { + $._PPP_.updateEventPanel(app.project.name + " successfully processed to " + outFolder.fsName + "."); + } + return result; + } + } + + + } + if (pmo) { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "Output Presets:*.epr"; + } + + var outFolder = Folder.selectDialog("Choose output directory."); + if (outFolder) { + + var presetPath = ""; + var useSpecificPreset = confirm("Would you like to select an output preset?", false, "Are you sure...?"); + if (useSpecificPreset){ + var useThisEPR = File.openDialog ( "Choose output preset (.epr file)", // title + filterString, // filter available files? + false); // allow multiple? + + if (useThisEPR){ + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_PRESET; + pmo.encoderPresetFilePath = useThisEPR.fsName; + } + } else { + pmo.clipTranscoderOption = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE; + } + + var processAllSequences = confirm("Process all sequences? No = just the first sequence found.", true, "Process all?"); + + if (processAllSequences){ + pmo.includeAllSequences = true; + } else { + pmo.includeAllSequences = false; + pmo.affectedSequences = [app.project.sequences[0]]; + } + + pmo.clipTransferOption = pmo.CLIP_TRANSFER_TRANSCODE; + pmo.convertAECompsToClips = false; + pmo.convertSyntheticsToClips = false; + pmo.copyToPreventAlphaLoss = false; + pmo.destinationPath = outFolder.fsName; + pmo.excludeUnused = false; + pmo.handleFrameCount = 0; + pmo.includeConformedAudio = true; + pmo.includePreviews = true; + pmo.renameMedia = false; + + var result = app.projectManager.process(app.project); + var errorList = app.projectManager.errors; + + if(errorList.length){ + for (var k = 0; k < errorList.length; k++){ + $._PPP_.updateEventPanel(errorList[k][1]); + } + } else { + $._PPP_.updateEventPanel(app.project.name + " successfully processed to " + outFolder.fsName + "."); + } + return result; + } + } + }, + + importMoGRT : function () { + var activeSeq = app.project.activeSequence; + if (activeSeq) { + var filterString = ""; + if (Folder.fs === 'Windows'){ + filterString = "Motion Graphics Templates:*.mogrt"; + } + var mogrtToImport = File.openDialog ( "Choose MoGRT", // title + filterString, // filter available files? + false); // allow multiple? + if (mogrtToImport){ + var targetTime = activeSeq.getPlayerPosition(); + var vidTrackOffset = 0; + var audTrackOffset = 0; + var newTrackItem = activeSeq.importMGT( mogrtToImport.fsName, + targetTime.ticks, + vidTrackOffset, + audTrackOffset); + if (newTrackItem){ + var moComp = newTrackItem.getMGTComponent(); + if (moComp){ + var params = moComp.properties; + for (var z = 0; z < params.numItems; z++){ + var thisParam = params[0]; + } + var srcTextParam = params.getParamForDisplayName("Main Title"); + if (srcTextParam){ + var val = srcTextParam.getValue(); + srcTextParam.setValue("New value set by PProPanel!"); + } + } + } + } else { + app.setSDKEventMessage('Unable to import ' + mogrtToImport.fsName + '.', 'error'); + } + } else { + app.setSDKEventMessage('No active sequence.'); + } + }, + + reportCurrentProjectSelection : function() { + var viewIDs = app.getProjectViewIDs(); // sample code optimized for a single open project + viewSelection = app.getProjectViewSelection(viewIDs[0]); + $._PPP_.projectPanelSelectionChanged(viewSelection, viewIDs[0]); + }, + + randomizeProjectSelection : function() { + var viewIDs = app.getProjectViewIDs(); + var firstProject = app.getProjectFromViewID(viewIDs[0]); + var arrayOfRandomProjectItems = []; + + for (var b = 0; b < app.project.rootItem.children.numItems; b++){ + var currentProjectItem = app.project.rootItem.children[b]; + if (Math.random() > 0.5){ + arrayOfRandomProjectItems.push(currentProjectItem); + } + } + if (arrayOfRandomProjectItems.length > 0){ + app.setProjectViewSelection(arrayOfRandomProjectItems, viewIDs[0]); + } + }, + + setAllProjectItemsOnline : function(startingBin){ + for (var k = 0; k < startingBin.children.numItems; k++){ + var currentChild = startingBin.children[k]; + if (currentChild){ + if (currentChild.type === ProjectItemType.BIN){ + $._PPP_.setAllProjectItemsOnline(currentChild); // warning; recursion! + } else if (currentChild.isOffline()){ + currentChild.changeMediaPath(currentChild.getMediaPath(), true); + if (currentChild.isOffline()){ + $._PPP_.updateEventPanel("Failed to bring \'" + currentChild.name + "\' online."); + } else { + $._PPP_.updateEventPanel("\'" + currentChild.name + "\' is once again online."); + } + } + } + } + }, + + setAllOnline : function(){ + var startingBin = app.project.rootItem; + $._PPP_.setAllProjectItemsOnline(startingBin); + }, + + setOffline : function() { + var viewIDs = app.getProjectViewIDs(); + for (var a = 0; a < app.projects.numProjects; a++){ + var currentProject = app.getProjectFromViewID(viewIDs[a]); + if (currentProject){ + if (currentProject.documentID === app.project.documentID){ // We're in the right project! + var selectedItems = app.getProjectViewSelection(viewIDs[a]); + for (var b = 0; b < selectedItems.length; b++){ + var currentItem = selectedItems[b]; + if (currentItem){ + if ((!currentItem.isSequence()) && (currentItem.type !== ProjectItemType.BIN)){ // For every selected item which isn't a bin or sequence... + if (currentItem.isOffline()){ + $._PPP_.updateEventPanel("\'" + currentItem.name + "\'was already offline."); + } else { + var result = currentItem.setOffline(); + $._PPP_.updateEventPanel("\'" + currentItem.name + "\' is now offline."); + } + } + } + } + } + } + } + }, + + updateFrameRate : function() { + var item = app.project.rootItem.children[0]; + if (item) { + if ((item.type == ProjectItemType.FILE) || (item.type == ProjectItemType.CLIP)){ + // If there is an item, and it's either a clip or file... + item.setOverrideFrameRate(23.976); + } else { + $._PPP_.updateEventPanel('You cannot override the frame rate of bins or sequences.'); + } + } else { + $._PPP_.updateEventPanel("No project items found."); + } + }, + + onItemAddedToProject : function(whichProject, addedProjectItem) { + var msg = addedProjectItem.name + " was added to " + whichProject + "." + $._PPP_.updateEventPanel(msg); + }, + + registerItemAddedFxn : function() { + app.onItemAddedToProjectSuccess = $._PPP_.onItemAddedToProject; + }, + + myOnProjectChanged : function(documentID){ + var msg = 'Project with ID ' + documentID + ' Changed.'; + // Commented out, as this happens a LOT. + // $._PPP_.updateEventPanel(msg); + }, + + registerProjectChangedFxn : function() { + app.bind('onProjectChanged', $._PPP_.myOnProjectChanged); + }, + + confirmPProHostVersion : function() { + var version = parseFloat(app.version); + if (version < 12.1){ + $._PPP_.updateEventPanel("Note: PProPanel relies on features added in 12.1, but is currently running in " + version + "."); + } + }, + + changeMarkerColors : function() { + if (app.project.rootItem.children.numItems > 0){ + var projectItem = app.project.rootItem.children[0]; // assumes first item is footage. + if (projectItem) { + if (projectItem.type == ProjectItemType.CLIP || + projectItem.type == ProjectItemType.FILE) { + + markers = projectItem.getMarkers(); + + if (markers) { + var markerCount = markers.numMarkers; + + if (markerCount){ + for(var thisMarker = markers.getFirstMarker(); thisMarker !== undefined; thisMarker = markers.getNextMarker(thisMarker)){ + var oldColor = thisMarker.getColorByIndex(); + var newColor = oldColor + 1; + if (newColor > 7){ + newColor = 0; + } + thisMarker.setColorByIndex(newColor); + $._PPP_.updateEventPanel("Changed color of marker named \'" + thisMarker.name + "\' from " + oldColor + " to " + newColor + "."); + } + } + } + } else { + $._PPP_.updateEventPanel("Can only add markers to footage items."); + } + } else { + $._PPP_.updateEventPanel("Could not find first projectItem."); + } + } else { + $._PPP_.updateEventPanel("Project is empty."); + } + }, + + changeSeqTimeCodeDisplay : function() { + if (app.project.activeSequence){ + var currentSeqSettings = app.project.activeSequence.getSettings(); + if (currentSeqSettings){ + var oldVidSetting = currentSeqSettings.videoDisplayFormat; + currentSeqSettings.videoDisplayFormat = oldVidSetting + 1; + if (currentSeqSettings.videoDisplayFormat > TIMEDISPLAY_48Timecode){ + currentSeqSettings.videoDisplayFormat = TIMEDISPLAY_24Timecode; + } + app.project.activeSequence.setSettings(currentSeqSettings); + $._PPP_.updateEventPanel("Changed timecode display format for \'" + app.project.activeSequence.name + "\'."); + } + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + myActiveSequenceChangedFxn : function() { + $._PPP_.updateEventPanel("Active sequence is now " + app.project.activeSequence.name + "."); + }, + + myActiveSequenceSelectionChangedFxn : function() { + var sel = app.project.activeSequence.getSelection(); + $._PPP_.updateEventPanel('Current active sequence = ' + app.project.activeSequence.name + '.'); + $._PPP_.updateEventPanel( sel.length + ' track items selected.'); + for(var i = 0; i < sel.length; i++){ + if (sel[i].name !== 'anonymous'){ + $._PPP_.updateEventPanel('Selected item ' + (i+1) + ' == ' + sel[i].name + '.'); + } + } + }, + + registerActiveSequenceChangedFxn : function() { + var success = app.bind("onActiveSequenceChanged", $._PPP_.myActiveSequenceChangedFxn); + }, + + registerSequenceSelectionChangedFxn : function() { + var success = app.bind('onActiveSequenceSelectionChanged', $._PPP_.myActiveSequenceSelectionChangedFxn); + }, + + enableNewWorldScripting : function(){ + app.enableQE(); + + var previousNWValue = qe.getDebugDatabaseEntry("ScriptLayerPPro.EnableNewWorld"); + var previousInternalDOMValue = qe.getDebugDatabaseEntry("dvascripting.EnabledInternalDOM"); + if ((previousNWValue === 'true') && (previousInternalDOMValue === 'true')){ + qe.setDebugDatabaseEntry("ScriptLayerPPro.EnableNewWorld", "false"); + qe.setDebugDatabaseEntry("dvascripting.EnabledInternalDOM", "false"); + $._PPP_.updateEventPanel("ScriptLayerPPro.EnableNewWorld and dvascripting.EnabledInternalDOM are now OFF."); + } else { + qe.setDebugDatabaseEntry("ScriptLayerPPro.EnableNewWorld", "true"); + qe.setDebugDatabaseEntry("dvascripting.EnabledInternalDOM", "true"); + $._PPP_.updateEventPanel("ScriptLayerPPro.EnableNewWorld and dvascripting.EnabledInternalDOM are now ON."); + } + }, + + insertOrAppendToTopTracks : function() { + var seq = app.project.activeSequence; + if (seq){ + var first = app.project.rootItem.children[0]; + if (first){ + var time = seq.getPlayerPosition(); + var newClip = seq.insertClip(first, time, (seq.videoTracks.numTracks - 1), (seq.audioTracks.numTracks - 1)); + if (newClip){ + $._PPP_.updateEventPanel("Inserted " + newClip.name + ", into " + seq.name + "."); + } + } else { + $._PPP_.updateEventPanel("Couldn't locate first projectItem."); + } + } else { + $._PPP_.updateEventPanel("no active sequence."); + } + }, + + closeAllProjectsOtherThanActiveProject : function() { + var viewIDs = app.getProjectViewIDs(); + var closeTheseProjects = []; + for (var a = 0; a < viewIDs.length; a++){ + var thisProj = app.getProjectFromViewID(viewIDs[a]); + if (thisProj.documentID !== app.project.documentID){ + closeTheseProjects[a] = thisProj; + } + } + // Why do this afterward? Because if we close projects in that loop, we change the active project. :) + for (var b = 0; b < closeTheseProjects.length; b++){ + $._PPP_.updateEventPanel("Closed " + closeTheseProjects[b].name); + closeTheseProjects[b].closeDocument(); + } + }, + + countAdjustmentLayersInBin : function(parentItem, arrayOfAdjustmentLayerNames, foundSoFar){ + for (var j = 0; j < parentItem.children.numItems; j++){ + var currentChild = parentItem.children[j]; + if (currentChild){ + if (currentChild.type == ProjectItemType.BIN){ + $._PPP_.countAdjustmentLayersInBin(currentChild, arrayOfAdjustmentLayerNames, foundSoFar); // warning; recursion! + } else { + if (currentChild.isAdjustmentLayer()){ + arrayOfAdjustmentLayerNames[foundSoFar] = currentChild.name; + foundSoFar++; + } + } + } + } + }, + + findAllAdjustmentLayersInProject : function() { + var arrayOfAdjustmentLayerNames = []; + var foundSoFar = 0; + var startingBin = app.project.rootItem; + + $._PPP_.countAdjustmentLayersInBin(startingBin, arrayOfAdjustmentLayerNames, foundSoFar); + if (arrayOfAdjustmentLayerNames.length){ + var remainingArgs = arrayOfAdjustmentLayerNames.length; + var message = remainingArgs + " adjustment layers found: "; + + for (var i = 0; i < arrayOfAdjustmentLayerNames.length; i++) { + message += arrayOfAdjustmentLayerNames[i]; + remainingArgs--; + if (remainingArgs > 1) { + message += ', '; + } + if (remainingArgs === 1){ + message += ", and "; + } + if (remainingArgs === 0) { + message += "."; + } + } + $._PPP_.updateEventPanel(message); + } else { + $._PPP_.updateEventPanel("No adjustment layers found in " + app.project.name + "."); + } + }, + + consolidateDuplicates : function() { + result = app.project.consolidateDuplicates(); + $._PPP_.updateEventPanel("Duplicates consolidated in " + app.project.name + "."); + }, + + closeAllSequences : function() { + var seqList = app.project.sequences; + for (var a = 0; a < seqList.numSequences; a++){ + var currentSeq = seqList[a]; + if (currentSeq){ + currentSeq.close(); + } else { + $._PPP_.updateEventPanel("No sequences from " + app.project.name + " were open."); + } + } + }, + + dumpAllPresets : function() { + var desktopPath = new File("~/Desktop"); + var outputFileName = desktopPath.fsName + $._PPP_.getSep() + 'available_presets.txt'; + var selectedPreset = undefined; + var selectedExporter = undefined; + var exporters = app.encoder.getExporters(); + + var outFile = new File(outputFileName); + + outFile.encoding = "UTF8"; + outFile.open("w", "TEXT", "????"); + + for(var i = 0; i < exporters.length; i++){ + var exporter = exporters[i]; + if (exporter){ + outFile.writeln('-----------------------------------------------'); + outFile.writeln(i + ':' + exporter.name + ' : ' + exporter.classID + ' : ' + exporter.fileType); + var presets = exporter.getPresets(); + if (presets){ + outFile.writeln(presets.length + ' presets found'); + for(var j = 0; j < presets.length; j++){ + var preset = presets[j]; + if (preset){ + outFile.writeln('matchName: ' + preset.matchName + '(' + preset.name+')'); + if (preset.name.indexOf('TQM') > -1){ + selectedPreset = preset; + selectedExporter = exporter; + outFile.writeln('selected preset = ' + selectedExporter.name + ' : ' + selectedPreset.name); + selectedPreset.writeToFile(desktopPath.fsName + $._PPP_.getSep() + preset.name + ".epr"); + $._PPP_.updateEventPanel("List of available presets saved to desktop as \'available_presets.txt\'"); + } + } + } + } + } + } + desktopPath.close(); + outFile.close(); + }, + + reportSequenceVRSettings : function() { + var seq = app.project.activeSequence; + if (seq){ + var settings = seq.getSettings(); + if (settings){ + $._PPP_.updateEventPanel("===================================================="); + $._PPP_.updateEventPanel("VR Settings for \'" + seq.name + "\':"); + $._PPP_.updateEventPanel(""); + $._PPP_.updateEventPanel(" Horizontal captured view: " + settings.vrHorzCapturedView); + $._PPP_.updateEventPanel(" Vertical captured view: " + settings.vrVertCapturedView); + $._PPP_.updateEventPanel(" Layout: " + settings.Layout); + $._PPP_.updateEventPanel(" Projection: " + settings.vrProjection); + $._PPP_.updateEventPanel(""); + $._PPP_.updateEventPanel("===================================================="); + } + } + }, + + openProjectItemInSource : function() { + var viewIDs = app.getProjectViewIDs(); + if (viewIDs){ + for (var a = 0; a < app.projects.numProjects; a++){ + var currentProject = app.getProjectFromViewID(viewIDs[a]); + if (currentProject){ + if (currentProject.documentID === app.project.documentID){ // We're in the right project! + var selectedItems = app.getProjectViewSelection(viewIDs[a]); + for (var b = 0; b < selectedItems.length; b++){ + var currentItem = selectedItems[b]; + if (currentItem){ + if (currentItem.type !== ProjectItemType.BIN){ // For every selected item which isn't a bin or sequence... + app.sourceMonitor.openProjectItem(currentItem); + } + } else { + $._PPP_.updateEventPanel("No item available."); + } + } + } + } else { + $._PPP_.updateEventPanel("No project available."); + } + } + } else { + $._PPP_.updateEventPanel("No view IDs available."); + } + }, + + reinterpretFootage : function() { + var viewIDs = app.getProjectViewIDs(); + if (viewIDs){ + for (var a = 0; a < app.projects.numProjects; a++){ + var currentProject = app.getProjectFromViewID(viewIDs[a]); + if (currentProject){ + if (currentProject.documentID === app.project.documentID){ // We're in the right project! + var selectedItems = app.getProjectViewSelection(viewIDs[a]); + if (selectedItems){ + for (var b = 0; b < selectedItems.length; b++){ + var currentItem = selectedItems[b]; + if (currentItem){ + if ((currentItem.type !== ProjectItemType.BIN) && + (currentItem.isSequence() === false)){ + var interp = currentItem.getFootageInterpretation(); + if (interp) { + // Note: I made this something terrible, so the change is apparent. + interp.frameRate = 17.868; + interp.pixelAspectRatio = 1.2121; + currentItem.setFootageInterpretation(interp); + } else { + $._PPP_.updateEventPanel("Unable to get interpretation for " + currentItem.name + "."); + } + var mapping = currentItem.getAudioChannelMapping; + if (mapping){ + mapping.audioChannelsType = AUDIOCHANNELTYPE_Stereo; + mapping.audioClipsNumber = 1; + mapping.setMappingForChannel(0, 4); // 1st param = channel index, 2nd param = source index + mapping.setMappingForChannel(1, 5); + currentItem.setAudioChannelMapping(mapping); // submit changed mapping object + } + } + } else { + $._PPP_.updateEventPanel("No project item available."); + } + } + } else { + $._PPP_.updateEventPanel("No items selected."); + } + } + } else { + $._PPP_.updateEventPanel("No project available."); + } + } + } else { + $._PPP_.updateEventPanel("No view IDs available."); + } + }, + + createSubSequence : function() { + + /* Behavioral Note + + createSubSequence() uses track targeting to select clips when there is + no current clip selection, in the sequence. To create a subsequence with + clips on tracks that are currently NOT targeted, either select some clips + (on any track), or temporarily target all desired tracks. + + */ + + var activeSequence = app.project.activeSequence; + if (activeSequence) { + var foundTarget = false; + for (var a = 0; (a < activeSequence.videoTracks.numTracks) && (foundTarget === false); a++){ + var vTrack = activeSequence.videoTracks[a]; + if (vTrack){ + if (vTrack.isTargeted()){ + foundTarget = true; + } + } + } + // If no targeted track was found, just target the zero-th track, for demo purposes + if (foundTarget === false){ + activeSequence.videotracks[0].setTargeted(true, true); + } + + var cloneAnyway = true; + if ((activeSequence.getInPoint() == NOT_SET) && (activeSequence.getOutPoint() == NOT_SET)){ + cloneAnyway = confirm("No in or out points set; clone entire sequence?", false, "Clone the whole thing?"); + } + if (cloneAnyway){ + var ignoreMapping = confirm("Ignore track mapping?", false, "Ignore track mapping?"); + var newSeq = activeSequence.createSubsequence(ignoreMapping); + // rename newSeq here, as desired. + } + } else { + $._PPP_.updateEventPanel("No active sequence."); + } + }, + + selectAllRetimedClips : function() { + var activeSeq = app.project.activeSequence; + var numRetimedClips = 0; + if (activeSeq){ + var trackGroups = [ activeSeq.audioTracks, activeSeq.videoTracks ]; + var trackGroupNames = [ "audioTracks", "videoTracks" ]; + var updateUI = true; + + for(var gi = 0; gi<2; gi++) { + group = trackGroups[gi]; + for(var ti=0; ti} The file extensions (without the dot) for the types + * of files that can be selected. Ignored when chooseDirectory=true. + * + * @return An object with these properties: + *
  • "data": An array of the full names of the selected files.
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_INVALID_PARAMS
  • + *
+ **/ + native function ShowOpenDialog(); + cep.fs.showOpenDialog = function (allowMultipleSelection, chooseDirectory, title, initialPath, fileTypes) { + var resultString = ShowOpenDialog(allowMultipleSelection, chooseDirectory, + title || 'Open', initialPath || '', + fileTypes ? fileTypes.join(' ') : ''); + + var result = {data: JSON.parse(resultString || '[]'), err: getLastError() }; + return result; + }; + + /** + * Displays the OS File Open dialog, allowing the user to select files or directories. + * + * @param allowMultipleSelection {boolean} When true, multiple files/folders can be selected. + * @param chooseDirectory {boolean} When true, only folders can be selected. When false, only + * files can be selected. + * @param title {string} Title of the open dialog. + * @param initialPath {string} Initial path to display in the dialog. Pass NULL or "" to + * display the last path chosen. + * @param fileTypes {Array.} The file extensions (without the dot) for the types + * of files that can be selected. Ignored when chooseDirectory=true. + * @param friendlyFilePrefix {string} String to put in front of the extensions + * of files that can be selected. Ignored when chooseDirectory=true. (win only) + * For example: + * fileTypes = ["gif", "jpg", "jpeg", "png", "bmp", "webp", "svg"]; + * friendlyFilePrefix = "Images (*.gif;*.jpg;*.jpeg;*.png;*.bmp;*.webp;*.svg)"; + * @param prompt {string} String for OK button (mac only, default is "Open" on mac, "Open" or "Select Folder" on win). + * + * @return An object with these properties: + *
  • "data": An array of the full names of the selected files.
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_INVALID_PARAMS
  • + *
+ **/ + native function ShowOpenDialogEx(); + cep.fs.showOpenDialogEx = function (allowMultipleSelection, chooseDirectory, title, initialPath, fileTypes, + friendlyFilePrefix, prompt) { + var resultString = ShowOpenDialogEx(allowMultipleSelection, chooseDirectory, + title || 'Open', initialPath || '', + fileTypes ? fileTypes.join(' ') : '', friendlyFilePrefix || '', + prompt || ''); + + var result = {data: JSON.parse(resultString || '[]'), err: getLastError() }; + return result; + }; + + /** + * Displays the OS File Save dialog, allowing the user to type in a file name. + * + * @param title {string} Title of the save dialog. + * @param initialPath {string} Initial path to display in the dialog. Pass NULL or "" to + * display the last path chosen. + * @param fileTypes {Array.} The file extensions (without the dot) for the types + * of files that can be selected. + * @param defaultName {string} String to start with for the file name. + * @param friendlyFilePrefix {string} String to put in front of the extensions of files that can be selected. (win only) + * For example: + * fileTypes = ["gif", "jpg", "jpeg", "png", "bmp", "webp", "svg"]; + * friendlyFilePrefix = "Images (*.gif;*.jpg;*.jpeg;*.png;*.bmp;*.webp;*.svg)"; + * @param prompt {string} String for Save button (mac only, default is "Save" on mac and win). + * @param nameFieldLabel {string} String displayed in front of the file name text field (mac only, "File name:" on win). + * + * @return An object with these properties: + *
  • "data": The file path selected to save at or "" if canceled
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_INVALID_PARAMS
  • + *
+ **/ + native function ShowSaveDialogEx(); + cep.fs.showSaveDialogEx = function (title, initialPath, fileTypes, defaultName, friendlyFilePrefix, prompt, nameFieldLabel) { + var resultString = ShowSaveDialogEx(title || '', initialPath || '', + fileTypes ? fileTypes.join(' ') : '', defaultName || '', + friendlyFilePrefix || '', prompt || '', nameFieldLabel || ''); + + var result = {data: resultString || '', err: getLastError() }; + return result; + }; + + /** + * Reads the contents of a folder. + * + * @param path {string} The path of the folder to read. + * + * @return An object with these properties: + *
  • "data": An array of the names of the contained files (excluding '.' and '..'.
  • + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_NOT_FOUND + *
    ERR_CANT_READ
+ **/ + native function ReadDir(); + cep.fs.readdir = function (path) { + var resultString = ReadDir(path); + var result = {data: JSON.parse(resultString || '[]'), err: getLastError() }; + return result; + }; + + /** + * Creates a new folder. + * + * @param path {string} The path of the folder to create. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS
+ **/ + native function MakeDir(); + cep.fs.makedir = function (path) { + MakeDir(path); + return getErrorResult(); + }; + + /** + * Renames a file or folder. + * + * @param oldPath {string} The old name of the file or folder. + * @param newPath {string} The new name of the file or folder. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_NOT_FOUND + *
    ERR_FILE_EXISTS
+ **/ + native function Rename(); + cep.fs.rename = function(oldPath, newPath) { + Rename(oldPath, newPath); + return getErrorResult(); + }; + + /** + * Reports whether an item is a file or folder. + * + * @param path {string} The path of the file or folder. + * + * @return An object with these properties: + *
  • "data": An object with properties + *
    isFile (boolean) + *
    isDirectory (boolean) + *
    mtime (modification DateTime)
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_NOT_FOUND
  • + *
+ **/ + native function IsDirectory(); + native function GetFileModificationTime(); + cep.fs.stat = function (path) { + var isDir = IsDirectory(path); + var modtime = GetFileModificationTime(path); + var result = { + data: { + isFile: function () { + return !isDir; + }, + isDirectory: function () { + return isDir; + }, + mtime: modtime + }, + err: getLastError() + }; + + return result; + }; + + /** + * Reads the entire contents of a file. + * + * @param path {string} The path of the file to read. + * @param encoding {string} The encoding of the contents of file, one of + * UTF8 (the default) or Base64. + * + * @return An object with these properties: + *
  • "data": The file contents.
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_NOT_FOUND + *
    ERR_CANT_READ + *
    ERR_UNSUPPORTED_ENCODING
  • + *
+ **/ + native function ReadFile(); + cep.fs.readFile = function (path, encoding) { + encoding = encoding ? encoding : cep.encoding.UTF8; + var contents = ReadFile(path, encoding); + var result = {data: contents, err: getLastError() }; + return result; + }; + + /** + * Writes data to a file, replacing the file if it already exists. + * + * @param path {string} The path of the file to write. + * @param data {string} The data to write to the file. + * @param encoding {string} The encoding of the contents of file, one of + * UTF8 (the default) or Base64. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_UNSUPPORTED_ENCODING + *
    ERR_CANT_WRITE + *
    ERR_OUT_OF_SPACE
+ **/ + native function WriteFile(); + cep.fs.writeFile = function (path, data, encoding) { + encoding = encoding ? encoding : cep.encoding.UTF8; + WriteFile(path, data, encoding); + return getErrorResult(); + }; + + /** + * Sets permissions for a file or folder. + * + * @param path {string} The path of the file or folder. + * @param mode {number} The permissions in numeric format (for example, 0777). + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_CANT_WRITE
+ **/ + native function SetPosixPermissions(); + cep.fs.chmod = function (path, mode) { + SetPosixPermissions(path, mode); + return getErrorResult(); + }; + + /** + * Deletes a file. + * + * @param path {string} The path of the file to delete. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_NOT_FOUND + *
    ERR_NOT_FILE
+ **/ + native function DeleteFileOrDirectory(); + native function IsDirectory(); + cep.fs.deleteFile = function (path) { + if (IsDirectory(path)) { + var result = {err: cep.fs.ERR_NOT_FILE}; + return result; + } + DeleteFileOrDirectory(path); + return getErrorResult(); + }; + + /** + * Creates a process. + * + * @param arguments {list} The arguments to create process. The first one is the full path of the executable, + * followed by the arguments of the executable. + * + * @return An object with these properties: + *
  • "data": The pid of the process, or -1 on error.
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_EXCEED_MAX_NUM_PROCESS + *
    ERR_NOT_FOUND + *
    ERR_NOT_FILE
  • + *
+ **/ + native function CreateProcess(); + cep.process.createProcess = function () { + var args = Array.prototype.slice.call(arguments); + var pid = CreateProcess(args); + var result = {data: pid, err: getLastError()}; + return result; + }; + + /** + * Registers a standard-output handler for a process. + * + * @param pid {int} The pid of the process. + * @param callback {function} The handler function for the standard output callback. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function SetupStdOutHandler(); + cep.process.stdout = function (pid, callback) { + SetupStdOutHandler(pid, callback); + return getErrorResult(); + }; + + /** + * Registers up a standard-error handler for a process. + * + * @param pid {int} The pid of the process. + * @param callback {function} The handler function for the standard error callback. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function SetupStdErrHandler(); + cep.process.stderr = function (pid, callback) { + SetupStdErrHandler(pid, callback); + return getErrorResult(); + }; + + /** + * Writes data to the standard input of a process. + * + * @param pid {int} The pid of the process + * @param data {string} The data to write. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function WriteStdIn(); + cep.process.stdin = function (pid, data) { + WriteStdIn(pid, data); + return getErrorResult(); + }; + + /** + * Retrieves the working directory of a process. + * + * @param pid {int} The pid of the process. + * + * @return An object with these properties: + *
  • "data": The path of the working directory.
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function GetWorkingDirectory(); + cep.process.getWorkingDirectory = function (pid) { + var wd = GetWorkingDirectory(pid); + var result = {data: wd, err: getLastError()}; + return result; + }; + + /** + * Waits for a process to quit. + * + * @param pid {int} The pid of the process. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function WaitFor(); + cep.process.waitfor = function (pid) { + WaitFor(pid); + return getErrorResult(); + }; + + /** + * Registers a handler for the onquit callback of a process. + * + * @param pid {int} The pid of the process. + * @param callback {function} The handler function. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function OnQuit(); + cep.process.onquit = function (pid, callback) { + OnQuit(pid, callback); + return getErrorResult(); + }; + + /** + * Reports whether a process is currently running. + * + * @param pid {int} The pid of the process. + * + * @return An object with these properties: + *
  • "data": True if the process is running, false otherwise.
  • + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function IsRunning(); + cep.process.isRunning = function (pid) { + var isRunning = IsRunning(pid); + var result = {data: isRunning, err: getLastError()}; + return result; + }; + + /** + * Terminates a process. + * + * @param pid {int} The pid of the process + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS + *
    ERR_INVALID_PROCESS_ID
+ **/ + native function Terminate(); + cep.process.terminate = function (pid) { + Terminate(pid); + return getErrorResult(); + }; + + /** + * Encoding conversions. + * + */ + cep.encoding.convertion = + { + utf8_to_b64: function(str) { + return window.btoa(unescape(encodeURIComponent(str))); + }, + + b64_to_utf8: function(base64str) { + // If a base64 string contains any whitespace character, DOM Exception 5 occurs during window.atob, please see + // http://stackoverflow.com/questions/14695988/dom-exception-5-invalid-character-error-on-valid-base64-image-string-in-javascri + base64str = base64str.replace(/\s/g, ''); + return decodeURIComponent(escape(window.atob(base64str))); + }, + + binary_to_b64: function(binary) { + return window.btoa(binary); + }, + + b64_to_binary: function(base64str) { + return window.atob(base64str); + }, + + ascii_to_b64: function(ascii) { + return window.btoa(binary); + }, + + b64_to_ascii: function(base64str) { + return window.atob(base64str); + } + }; + + /** + * Opens a page in the default system browser. + * + * @param url {string} The URL of the page/file to open, or the email address. + * Must use HTTP/HTTPS/file/mailto. For example: + * "http://www.adobe.com" + * "https://github.com" + * "file:///C:/log.txt" + * "mailto:test@adobe.com" + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_UNKNOWN + *
    ERR_INVALID_PARAMS
+ **/ + native function OpenURLInDefaultBrowser(); + cep.util.openURLInDefaultBrowser = function (url) { + if (url && (url.indexOf("http://") === 0 || + url.indexOf("https://") === 0 || + url.indexOf("file://") === 0 || + url.indexOf("mailto:") === 0)) { + OpenURLInDefaultBrowser(url); + return getErrorResult(); + } else { + return { err : cep.util.ERR_INVALID_URL }; + } + }; + + /** + * Registers a callback function for extension unload. If called more than once, + * the last callback that is successfully registered is used. + * + * @deprecated since version 6.0.0 + * + * @param callback {function} The handler function. + * + * @return An object with this property: + *
  • "err": The status of the operation, one of: + *
    NO_ERROR + *
    ERR_INVALID_PARAMS
+ **/ + native function RegisterExtensionUnloadCallback(); + cep.util.registerExtensionUnloadCallback = function (callback) { + return { err : cep.util.DEPRECATED_API }; + }; + + /** + * Stores the user's proxy credentials + * + * @param username {string} proxy username + * @param password {string} proxy password + * + * @return An object with this property: + *
  • "err": The status of the operation, one of + *
    NO_ERROR + *
    ERR_INVALID_PARAMS
  • + *
+ **/ + native function StoreProxyCredentials(); + cep.util.storeProxyCredentials = function (username, password) { + StoreProxyCredentials(username, password); + return getErrorResult(); + }; + +})(); diff --git a/pype/premiere/extensions/com.pype.rename/lib/CSInterface.js b/pype/premiere/extensions/com.pype.rename/lib/CSInterface.js new file mode 100644 index 0000000000..e2a6e02eb2 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/lib/CSInterface.js @@ -0,0 +1,1291 @@ +/************************************************************************************************** +* +* ADOBE SYSTEMS INCORPORATED +* Copyright 2013 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the +* terms of the Adobe license agreement accompanying it. If you have received this file from a +* source other than Adobe, then your use, modification, or distribution of it requires the prior +* written permission of Adobe. +* +**************************************************************************************************/ + +/** CSInterface - v9.2.0 */ + +/** + * Stores constants for the window types supported by the CSXS infrastructure. + */ +function CSXSWindowType() +{ +} + +/** Constant for the CSXS window type Panel. */ +CSXSWindowType._PANEL = "Panel"; + +/** Constant for the CSXS window type Modeless. */ +CSXSWindowType._MODELESS = "Modeless"; + +/** Constant for the CSXS window type ModalDialog. */ +CSXSWindowType._MODAL_DIALOG = "ModalDialog"; + +/** EvalScript error message */ +EvalScript_ErrMessage = "EvalScript error."; + +/** + * @class Version + * Defines a version number with major, minor, micro, and special + * components. The major, minor and micro values are numeric; the special + * value can be any string. + * + * @param major The major version component, a positive integer up to nine digits long. + * @param minor The minor version component, a positive integer up to nine digits long. + * @param micro The micro version component, a positive integer up to nine digits long. + * @param special The special version component, an arbitrary string. + * + * @return A new \c Version object. + */ +function Version(major, minor, micro, special) +{ + this.major = major; + this.minor = minor; + this.micro = micro; + this.special = special; +} + +/** + * The maximum value allowed for a numeric version component. + * This reflects the maximum value allowed in PlugPlug and the manifest schema. + */ +Version.MAX_NUM = 999999999; + +/** + * @class VersionBound + * Defines a boundary for a version range, which associates a \c Version object + * with a flag for whether it is an inclusive or exclusive boundary. + * + * @param version The \c #Version object. + * @param inclusive True if this boundary is inclusive, false if it is exclusive. + * + * @return A new \c VersionBound object. + */ +function VersionBound(version, inclusive) +{ + this.version = version; + this.inclusive = inclusive; +} + +/** + * @class VersionRange + * Defines a range of versions using a lower boundary and optional upper boundary. + * + * @param lowerBound The \c #VersionBound object. + * @param upperBound The \c #VersionBound object, or null for a range with no upper boundary. + * + * @return A new \c VersionRange object. + */ +function VersionRange(lowerBound, upperBound) +{ + this.lowerBound = lowerBound; + this.upperBound = upperBound; +} + +/** + * @class Runtime + * Represents a runtime related to the CEP infrastructure. + * Extensions can declare dependencies on particular + * CEP runtime versions in the extension manifest. + * + * @param name The runtime name. + * @param version A \c #VersionRange object that defines a range of valid versions. + * + * @return A new \c Runtime object. + */ +function Runtime(name, versionRange) +{ + this.name = name; + this.versionRange = versionRange; +} + +/** +* @class Extension +* Encapsulates a CEP-based extension to an Adobe application. +* +* @param id The unique identifier of this extension. +* @param name The localizable display name of this extension. +* @param mainPath The path of the "index.html" file. +* @param basePath The base path of this extension. +* @param windowType The window type of the main window of this extension. + Valid values are defined by \c #CSXSWindowType. +* @param width The default width in pixels of the main window of this extension. +* @param height The default height in pixels of the main window of this extension. +* @param minWidth The minimum width in pixels of the main window of this extension. +* @param minHeight The minimum height in pixels of the main window of this extension. +* @param maxWidth The maximum width in pixels of the main window of this extension. +* @param maxHeight The maximum height in pixels of the main window of this extension. +* @param defaultExtensionDataXml The extension data contained in the default \c ExtensionDispatchInfo section of the extension manifest. +* @param specialExtensionDataXml The extension data contained in the application-specific \c ExtensionDispatchInfo section of the extension manifest. +* @param requiredRuntimeList An array of \c Runtime objects for runtimes required by this extension. +* @param isAutoVisible True if this extension is visible on loading. +* @param isPluginExtension True if this extension has been deployed in the Plugins folder of the host application. +* +* @return A new \c Extension object. +*/ +function Extension(id, name, mainPath, basePath, windowType, width, height, minWidth, minHeight, maxWidth, maxHeight, + defaultExtensionDataXml, specialExtensionDataXml, requiredRuntimeList, isAutoVisible, isPluginExtension) +{ + this.id = id; + this.name = name; + this.mainPath = mainPath; + this.basePath = basePath; + this.windowType = windowType; + this.width = width; + this.height = height; + this.minWidth = minWidth; + this.minHeight = minHeight; + this.maxWidth = maxWidth; + this.maxHeight = maxHeight; + this.defaultExtensionDataXml = defaultExtensionDataXml; + this.specialExtensionDataXml = specialExtensionDataXml; + this.requiredRuntimeList = requiredRuntimeList; + this.isAutoVisible = isAutoVisible; + this.isPluginExtension = isPluginExtension; +} + +/** + * @class CSEvent + * A standard JavaScript event, the base class for CEP events. + * + * @param type The name of the event type. + * @param scope The scope of event, can be "GLOBAL" or "APPLICATION". + * @param appId The unique identifier of the application that generated the event. + * @param extensionId The unique identifier of the extension that generated the event. + * + * @return A new \c CSEvent object + */ +function CSEvent(type, scope, appId, extensionId) +{ + this.type = type; + this.scope = scope; + this.appId = appId; + this.extensionId = extensionId; +} + +/** Event-specific data. */ +CSEvent.prototype.data = ""; + +/** + * @class SystemPath + * Stores operating-system-specific location constants for use in the + * \c #CSInterface.getSystemPath() method. + * @return A new \c SystemPath object. + */ +function SystemPath() +{ +} + +/** The path to user data. */ +SystemPath.USER_DATA = "userData"; + +/** The path to common files for Adobe applications. */ +SystemPath.COMMON_FILES = "commonFiles"; + +/** The path to the user's default document folder. */ +SystemPath.MY_DOCUMENTS = "myDocuments"; + +/** @deprecated. Use \c #SystemPath.Extension. */ +SystemPath.APPLICATION = "application"; + +/** The path to current extension. */ +SystemPath.EXTENSION = "extension"; + +/** The path to hosting application's executable. */ +SystemPath.HOST_APPLICATION = "hostApplication"; + +/** + * @class ColorType + * Stores color-type constants. + */ +function ColorType() +{ +} + +/** RGB color type. */ +ColorType.RGB = "rgb"; + +/** Gradient color type. */ +ColorType.GRADIENT = "gradient"; + +/** Null color type. */ +ColorType.NONE = "none"; + +/** + * @class RGBColor + * Stores an RGB color with red, green, blue, and alpha values. + * All values are in the range [0.0 to 255.0]. Invalid numeric values are + * converted to numbers within this range. + * + * @param red The red value, in the range [0.0 to 255.0]. + * @param green The green value, in the range [0.0 to 255.0]. + * @param blue The blue value, in the range [0.0 to 255.0]. + * @param alpha The alpha (transparency) value, in the range [0.0 to 255.0]. + * The default, 255.0, means that the color is fully opaque. + * + * @return A new RGBColor object. + */ +function RGBColor(red, green, blue, alpha) +{ + this.red = red; + this.green = green; + this.blue = blue; + this.alpha = alpha; +} + +/** + * @class Direction + * A point value in which the y component is 0 and the x component + * is positive or negative for a right or left direction, + * or the x component is 0 and the y component is positive or negative for + * an up or down direction. + * + * @param x The horizontal component of the point. + * @param y The vertical component of the point. + * + * @return A new \c Direction object. + */ +function Direction(x, y) +{ + this.x = x; + this.y = y; +} + +/** + * @class GradientStop + * Stores gradient stop information. + * + * @param offset The offset of the gradient stop, in the range [0.0 to 1.0]. + * @param rgbColor The color of the gradient at this point, an \c #RGBColor object. + * + * @return GradientStop object. + */ +function GradientStop(offset, rgbColor) +{ + this.offset = offset; + this.rgbColor = rgbColor; +} + +/** + * @class GradientColor + * Stores gradient color information. + * + * @param type The gradient type, must be "linear". + * @param direction A \c #Direction object for the direction of the gradient + (up, down, right, or left). + * @param numStops The number of stops in the gradient. + * @param gradientStopList An array of \c #GradientStop objects. + * + * @return A new \c GradientColor object. + */ +function GradientColor(type, direction, numStops, arrGradientStop) +{ + this.type = type; + this.direction = direction; + this.numStops = numStops; + this.arrGradientStop = arrGradientStop; +} + +/** + * @class UIColor + * Stores color information, including the type, anti-alias level, and specific color + * values in a color object of an appropriate type. + * + * @param type The color type, 1 for "rgb" and 2 for "gradient". + The supplied color object must correspond to this type. + * @param antialiasLevel The anti-alias level constant. + * @param color A \c #RGBColor or \c #GradientColor object containing specific color information. + * + * @return A new \c UIColor object. + */ +function UIColor(type, antialiasLevel, color) +{ + this.type = type; + this.antialiasLevel = antialiasLevel; + this.color = color; +} + +/** + * @class AppSkinInfo + * Stores window-skin properties, such as color and font. All color parameter values are \c #UIColor objects except that systemHighlightColor is \c #RGBColor object. + * + * @param baseFontFamily The base font family of the application. + * @param baseFontSize The base font size of the application. + * @param appBarBackgroundColor The application bar background color. + * @param panelBackgroundColor The background color of the extension panel. + * @param appBarBackgroundColorSRGB The application bar background color, as sRGB. + * @param panelBackgroundColorSRGB The background color of the extension panel, as sRGB. + * @param systemHighlightColor The highlight color of the extension panel, if provided by the host application. Otherwise, the operating-system highlight color. + * + * @return AppSkinInfo object. + */ +function AppSkinInfo(baseFontFamily, baseFontSize, appBarBackgroundColor, panelBackgroundColor, appBarBackgroundColorSRGB, panelBackgroundColorSRGB, systemHighlightColor) +{ + this.baseFontFamily = baseFontFamily; + this.baseFontSize = baseFontSize; + this.appBarBackgroundColor = appBarBackgroundColor; + this.panelBackgroundColor = panelBackgroundColor; + this.appBarBackgroundColorSRGB = appBarBackgroundColorSRGB; + this.panelBackgroundColorSRGB = panelBackgroundColorSRGB; + this.systemHighlightColor = systemHighlightColor; +} + +/** + * @class HostEnvironment + * Stores information about the environment in which the extension is loaded. + * + * @param appName The application's name. + * @param appVersion The application's version. + * @param appLocale The application's current license locale. + * @param appUILocale The application's current UI locale. + * @param appId The application's unique identifier. + * @param isAppOnline True if the application is currently online. + * @param appSkinInfo An \c #AppSkinInfo object containing the application's default color and font styles. + * + * @return A new \c HostEnvironment object. + */ +function HostEnvironment(appName, appVersion, appLocale, appUILocale, appId, isAppOnline, appSkinInfo) +{ + this.appName = appName; + this.appVersion = appVersion; + this.appLocale = appLocale; + this.appUILocale = appUILocale; + this.appId = appId; + this.isAppOnline = isAppOnline; + this.appSkinInfo = appSkinInfo; +} + +/** + * @class HostCapabilities + * Stores information about the host capabilities. + * + * @param EXTENDED_PANEL_MENU True if the application supports panel menu. + * @param EXTENDED_PANEL_ICONS True if the application supports panel icon. + * @param DELEGATE_APE_ENGINE True if the application supports delegated APE engine. + * @param SUPPORT_HTML_EXTENSIONS True if the application supports HTML extensions. + * @param DISABLE_FLASH_EXTENSIONS True if the application disables FLASH extensions. + * + * @return A new \c HostCapabilities object. + */ +function HostCapabilities(EXTENDED_PANEL_MENU, EXTENDED_PANEL_ICONS, DELEGATE_APE_ENGINE, SUPPORT_HTML_EXTENSIONS, DISABLE_FLASH_EXTENSIONS) +{ + this.EXTENDED_PANEL_MENU = EXTENDED_PANEL_MENU; + this.EXTENDED_PANEL_ICONS = EXTENDED_PANEL_ICONS; + this.DELEGATE_APE_ENGINE = DELEGATE_APE_ENGINE; + this.SUPPORT_HTML_EXTENSIONS = SUPPORT_HTML_EXTENSIONS; + this.DISABLE_FLASH_EXTENSIONS = DISABLE_FLASH_EXTENSIONS; // Since 5.0.0 +} + +/** + * @class ApiVersion + * Stores current api version. + * + * Since 4.2.0 + * + * @param major The major version + * @param minor The minor version. + * @param micro The micro version. + * + * @return ApiVersion object. + */ +function ApiVersion(major, minor, micro) +{ + this.major = major; + this.minor = minor; + this.micro = micro; +} + +/** + * @class MenuItemStatus + * Stores flyout menu item status + * + * Since 5.2.0 + * + * @param menuItemLabel The menu item label. + * @param enabled True if user wants to enable the menu item. + * @param checked True if user wants to check the menu item. + * + * @return MenuItemStatus object. + */ +function MenuItemStatus(menuItemLabel, enabled, checked) +{ + this.menuItemLabel = menuItemLabel; + this.enabled = enabled; + this.checked = checked; +} + +/** + * @class ContextMenuItemStatus + * Stores the status of the context menu item. + * + * Since 5.2.0 + * + * @param menuItemID The menu item id. + * @param enabled True if user wants to enable the menu item. + * @param checked True if user wants to check the menu item. + * + * @return MenuItemStatus object. + */ +function ContextMenuItemStatus(menuItemID, enabled, checked) +{ + this.menuItemID = menuItemID; + this.enabled = enabled; + this.checked = checked; +} +//------------------------------ CSInterface ---------------------------------- + +/** + * @class CSInterface + * This is the entry point to the CEP extensibility infrastructure. + * Instantiate this object and use it to: + *
    + *
  • Access information about the host application in which an extension is running
  • + *
  • Launch an extension
  • + *
  • Register interest in event notifications, and dispatch events
  • + *
+ * + * @return A new \c CSInterface object + */ +function CSInterface() +{ +} + +/** + * User can add this event listener to handle native application theme color changes. + * Callback function gives extensions ability to fine-tune their theme color after the + * global theme color has been changed. + * The callback function should be like below: + * + * @example + * // event is a CSEvent object, but user can ignore it. + * function OnAppThemeColorChanged(event) + * { + * // Should get a latest HostEnvironment object from application. + * var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo; + * // Gets the style information such as color info from the skinInfo, + * // and redraw all UI controls of your extension according to the style info. + * } + */ +CSInterface.THEME_COLOR_CHANGED_EVENT = "com.adobe.csxs.events.ThemeColorChanged"; + +/** The host environment data object. */ +CSInterface.prototype.hostEnvironment = window.__adobe_cep__ ? JSON.parse(window.__adobe_cep__.getHostEnvironment()) : null; + +/** Retrieves information about the host environment in which the + * extension is currently running. + * + * @return A \c #HostEnvironment object. + */ +CSInterface.prototype.getHostEnvironment = function() +{ + this.hostEnvironment = JSON.parse(window.__adobe_cep__.getHostEnvironment()); + return this.hostEnvironment; +}; + +/** Loads binary file created which is located at url asynchronously +* +*@param urlName url at which binary file is located. Local files should start with 'file://' +*@param callback Optional. A callback function that returns after binary is loaded + +*@example +* To create JS binary use command ./cep_compiler test.js test.bin +* To load JS binary asyncronously +* var CSLib = new CSInterface(); +* CSLib.loadBinAsync(url, function () { }); +*/ +CSInterface.prototype.loadBinAsync = function(urlName,callback) +{ + try + { + var xhr = new XMLHttpRequest(); + xhr.responseType = 'arraybuffer'; // make response as ArrayBuffer + xhr.open('GET', urlName, true); + xhr.onerror = function () + { + console.log("Unable to load snapshot from given URL"); + return false; + }; + xhr.send(); + xhr.onload = () => { + window.__adobe_cep__.loadSnapshot(xhr.response); + if (typeof callback === "function") + { + callback(); + } + else if(typeof callback !== "undefined") + { + console.log("Provided callback is not a function"); + } + } + } + catch(err) + { + console.log(err); + return false; + } + + return true; +}; + +/** Loads binary file created synchronously +* +*@param pathName the local path at which binary file is located + +*@example +* To create JS binary use command ./cep_compiler test.js test.bin +* To load JS binary syncronously +* var CSLib = new CSInterface(); +* CSLib.loadBinSync(path); +*/ +CSInterface.prototype.loadBinSync = function(pathName) +{ + try + { + var OSVersion = this.getOSInformation(); + if(pathName.startsWith("file://")) + { + if (OSVersion.indexOf("Windows") >= 0) + { + pathName = pathName.replace("file:///", ""); + } + else if (OSVersion.indexOf("Mac") >= 0) + { + pathName = pathName.replace("file://", ""); + } + window.__adobe_cep__.loadSnapshot(pathName); + return true; + } + } + catch(err) + { + console.log(err); + return false; + } + //control should not come here + return false; +}; + +/** Closes this extension. */ +CSInterface.prototype.closeExtension = function() +{ + window.__adobe_cep__.closeExtension(); +}; + +/** + * Retrieves a path for which a constant is defined in the system. + * + * @param pathType The path-type constant defined in \c #SystemPath , + * + * @return The platform-specific system path string. + */ +CSInterface.prototype.getSystemPath = function(pathType) +{ + var path = decodeURI(window.__adobe_cep__.getSystemPath(pathType)); + var OSVersion = this.getOSInformation(); + if (OSVersion.indexOf("Windows") >= 0) + { + path = path.replace("file:///", ""); + } + else if (OSVersion.indexOf("Mac") >= 0) + { + path = path.replace("file://", ""); + } + return path; +}; + +/** + * Evaluates a JavaScript script, which can use the JavaScript DOM + * of the host application. + * + * @param script The JavaScript script. + * @param callback Optional. A callback function that receives the result of execution. + * If execution fails, the callback function receives the error message \c EvalScript_ErrMessage. + */ +CSInterface.prototype.evalScript = function(script, callback) +{ + if(callback === null || callback === undefined) + { + callback = function(result){}; + } + window.__adobe_cep__.evalScript(script, callback); +}; + +/** + * Retrieves the unique identifier of the application. + * in which the extension is currently running. + * + * @return The unique ID string. + */ +CSInterface.prototype.getApplicationID = function() +{ + var appId = this.hostEnvironment.appId; + return appId; +}; + +/** + * Retrieves host capability information for the application + * in which the extension is currently running. + * + * @return A \c #HostCapabilities object. + */ +CSInterface.prototype.getHostCapabilities = function() +{ + var hostCapabilities = JSON.parse(window.__adobe_cep__.getHostCapabilities() ); + return hostCapabilities; +}; + +/** + * Triggers a CEP event programmatically. Yoy can use it to dispatch + * an event of a predefined type, or of a type you have defined. + * + * @param event A \c CSEvent object. + */ +CSInterface.prototype.dispatchEvent = function(event) +{ + if (typeof event.data == "object") + { + event.data = JSON.stringify(event.data); + } + + window.__adobe_cep__.dispatchEvent(event); +}; + +/** + * Registers an interest in a CEP event of a particular type, and + * assigns an event handler. + * The event infrastructure notifies your extension when events of this type occur, + * passing the event object to the registered handler function. + * + * @param type The name of the event type of interest. + * @param listener The JavaScript handler function or method. + * @param obj Optional, the object containing the handler method, if any. + * Default is null. + */ +CSInterface.prototype.addEventListener = function(type, listener, obj) +{ + window.__adobe_cep__.addEventListener(type, listener, obj); +}; + +/** + * Removes a registered event listener. + * + * @param type The name of the event type of interest. + * @param listener The JavaScript handler function or method that was registered. + * @param obj Optional, the object containing the handler method, if any. + * Default is null. + */ +CSInterface.prototype.removeEventListener = function(type, listener, obj) +{ + window.__adobe_cep__.removeEventListener(type, listener, obj); +}; + +/** + * Loads and launches another extension, or activates the extension if it is already loaded. + * + * @param extensionId The extension's unique identifier. + * @param startupParams Not currently used, pass "". + * + * @example + * To launch the extension "help" with ID "HLP" from this extension, call: + * requestOpenExtension("HLP", ""); + * + */ +CSInterface.prototype.requestOpenExtension = function(extensionId, params) +{ + window.__adobe_cep__.requestOpenExtension(extensionId, params); +}; + +/** + * Retrieves the list of extensions currently loaded in the current host application. + * The extension list is initialized once, and remains the same during the lifetime + * of the CEP session. + * + * @param extensionIds Optional, an array of unique identifiers for extensions of interest. + * If omitted, retrieves data for all extensions. + * + * @return Zero or more \c #Extension objects. + */ +CSInterface.prototype.getExtensions = function(extensionIds) +{ + var extensionIdsStr = JSON.stringify(extensionIds); + var extensionsStr = window.__adobe_cep__.getExtensions(extensionIdsStr); + + var extensions = JSON.parse(extensionsStr); + return extensions; +}; + +/** + * Retrieves network-related preferences. + * + * @return A JavaScript object containing network preferences. + */ +CSInterface.prototype.getNetworkPreferences = function() +{ + var result = window.__adobe_cep__.getNetworkPreferences(); + var networkPre = JSON.parse(result); + + return networkPre; +}; + +/** + * Initializes the resource bundle for this extension with property values + * for the current application and locale. + * To support multiple locales, you must define a property file for each locale, + * containing keyed display-string values for that locale. + * See localization documentation for Extension Builder and related products. + * + * Keys can be in the + * form key.value="localized string", for use in HTML text elements. + * For example, in this input element, the localized \c key.value string is displayed + * instead of the empty \c value string: + * + * + * + * @return An object containing the resource bundle information. + */ +CSInterface.prototype.initResourceBundle = function() +{ + var resourceBundle = JSON.parse(window.__adobe_cep__.initResourceBundle()); + var resElms = document.querySelectorAll('[data-locale]'); + for (var n = 0; n < resElms.length; n++) + { + var resEl = resElms[n]; + // Get the resource key from the element. + var resKey = resEl.getAttribute('data-locale'); + if (resKey) + { + // Get all the resources that start with the key. + for (var key in resourceBundle) + { + if (key.indexOf(resKey) === 0) + { + var resValue = resourceBundle[key]; + if (key.length == resKey.length) + { + resEl.innerHTML = resValue; + } + else if ('.' == key.charAt(resKey.length)) + { + var attrKey = key.substring(resKey.length + 1); + resEl[attrKey] = resValue; + } + } + } + } + } + return resourceBundle; +}; + +/** + * Writes installation information to a file. + * + * @return The file path. + */ +CSInterface.prototype.dumpInstallationInfo = function() +{ + return window.__adobe_cep__.dumpInstallationInfo(); +}; + +/** + * Retrieves version information for the current Operating System, + * See http://www.useragentstring.com/pages/Chrome/ for Chrome \c navigator.userAgent values. + * + * @return A string containing the OS version, or "unknown Operation System". + * If user customizes the User Agent by setting CEF command parameter "--user-agent", only + * "Mac OS X" or "Windows" will be returned. + */ +CSInterface.prototype.getOSInformation = function() +{ + var userAgent = navigator.userAgent; + + if ((navigator.platform == "Win32") || (navigator.platform == "Windows")) + { + var winVersion = "Windows"; + var winBit = ""; + if (userAgent.indexOf("Windows") > -1) + { + if (userAgent.indexOf("Windows NT 5.0") > -1) + { + winVersion = "Windows 2000"; + } + else if (userAgent.indexOf("Windows NT 5.1") > -1) + { + winVersion = "Windows XP"; + } + else if (userAgent.indexOf("Windows NT 5.2") > -1) + { + winVersion = "Windows Server 2003"; + } + else if (userAgent.indexOf("Windows NT 6.0") > -1) + { + winVersion = "Windows Vista"; + } + else if (userAgent.indexOf("Windows NT 6.1") > -1) + { + winVersion = "Windows 7"; + } + else if (userAgent.indexOf("Windows NT 6.2") > -1) + { + winVersion = "Windows 8"; + } + else if (userAgent.indexOf("Windows NT 6.3") > -1) + { + winVersion = "Windows 8.1"; + } + else if (userAgent.indexOf("Windows NT 10") > -1) + { + winVersion = "Windows 10"; + } + + if (userAgent.indexOf("WOW64") > -1 || userAgent.indexOf("Win64") > -1) + { + winBit = " 64-bit"; + } + else + { + winBit = " 32-bit"; + } + } + + return winVersion + winBit; + } + else if ((navigator.platform == "MacIntel") || (navigator.platform == "Macintosh")) + { + var result = "Mac OS X"; + + if (userAgent.indexOf("Mac OS X") > -1) + { + result = userAgent.substring(userAgent.indexOf("Mac OS X"), userAgent.indexOf(")")); + result = result.replace(/_/g, "."); + } + + return result; + } + + return "Unknown Operation System"; +}; + +/** + * Opens a page in the default system browser. + * + * Since 4.2.0 + * + * @param url The URL of the page/file to open, or the email address. + * Must use HTTP/HTTPS/file/mailto protocol. For example: + * "http://www.adobe.com" + * "https://github.com" + * "file:///C:/log.txt" + * "mailto:test@adobe.com" + * + * @return One of these error codes:\n + *
    \n + *
  • NO_ERROR - 0
  • \n + *
  • ERR_UNKNOWN - 1
  • \n + *
  • ERR_INVALID_PARAMS - 2
  • \n + *
  • ERR_INVALID_URL - 201
  • \n + *
\n + */ +CSInterface.prototype.openURLInDefaultBrowser = function(url) +{ + return cep.util.openURLInDefaultBrowser(url); +}; + +/** + * Retrieves extension ID. + * + * Since 4.2.0 + * + * @return extension ID. + */ +CSInterface.prototype.getExtensionID = function() +{ + return window.__adobe_cep__.getExtensionId(); +}; + +/** + * Retrieves the scale factor of screen. + * On Windows platform, the value of scale factor might be different from operating system's scale factor, + * since host application may use its self-defined scale factor. + * + * Since 4.2.0 + * + * @return One of the following float number. + *
    \n + *
  • -1.0 when error occurs
  • \n + *
  • 1.0 means normal screen
  • \n + *
  • >1.0 means HiDPI screen
  • \n + *
\n + */ +CSInterface.prototype.getScaleFactor = function() +{ + return window.__adobe_cep__.getScaleFactor(); +}; + +/** + * Retrieves the scale factor of Monitor. + * + * Since 8.5.0 + * + * @return value >= 1.0f + * only available for windows machine + */ + if(navigator.appVersion.toLowerCase().indexOf("windows") >= 0) { + CSInterface.prototype.getMonitorScaleFactor = function() + { + return window.__adobe_cep__.getMonitorScaleFactor(); + }; +} + +/** + * Set a handler to detect any changes of scale factor. This only works on Mac. + * + * Since 4.2.0 + * + * @param handler The function to be called when scale factor is changed. + * + */ +CSInterface.prototype.setScaleFactorChangedHandler = function(handler) +{ + window.__adobe_cep__.setScaleFactorChangedHandler(handler); +}; + +/** + * Retrieves current API version. + * + * Since 4.2.0 + * + * @return ApiVersion object. + * + */ +CSInterface.prototype.getCurrentApiVersion = function() +{ + var apiVersion = JSON.parse(window.__adobe_cep__.getCurrentApiVersion()); + return apiVersion; +}; + +/** + * Set panel flyout menu by an XML. + * + * Since 5.2.0 + * + * Register a callback function for "com.adobe.csxs.events.flyoutMenuClicked" to get notified when a + * menu item is clicked. + * The "data" attribute of event is an object which contains "menuId" and "menuName" attributes. + * + * Register callback functions for "com.adobe.csxs.events.flyoutMenuOpened" and "com.adobe.csxs.events.flyoutMenuClosed" + * respectively to get notified when flyout menu is opened or closed. + * + * @param menu A XML string which describes menu structure. + * An example menu XML: + * + * + * + * + * + * + * + * + * + * + * + * + */ +CSInterface.prototype.setPanelFlyoutMenu = function(menu) +{ + if ("string" != typeof menu) + { + return; + } + + window.__adobe_cep__.invokeSync("setPanelFlyoutMenu", menu); +}; + +/** + * Updates a menu item in the extension window's flyout menu, by setting the enabled + * and selection status. + * + * Since 5.2.0 + * + * @param menuItemLabel The menu item label. + * @param enabled True to enable the item, false to disable it (gray it out). + * @param checked True to select the item, false to deselect it. + * + * @return false when the host application does not support this functionality (HostCapabilities.EXTENDED_PANEL_MENU is false). + * Fails silently if menu label is invalid. + * + * @see HostCapabilities.EXTENDED_PANEL_MENU + */ +CSInterface.prototype.updatePanelMenuItem = function(menuItemLabel, enabled, checked) +{ + var ret = false; + if (this.getHostCapabilities().EXTENDED_PANEL_MENU) + { + var itemStatus = new MenuItemStatus(menuItemLabel, enabled, checked); + ret = window.__adobe_cep__.invokeSync("updatePanelMenuItem", JSON.stringify(itemStatus)); + } + return ret; +}; + + +/** + * Set context menu by XML string. + * + * Since 5.2.0 + * + * There are a number of conventions used to communicate what type of menu item to create and how it should be handled. + * - an item without menu ID or menu name is disabled and is not shown. + * - if the item name is "---" (three hyphens) then it is treated as a separator. The menu ID in this case will always be NULL. + * - Checkable attribute takes precedence over Checked attribute. + * - a PNG icon. For optimal display results please supply a 16 x 16px icon as larger dimensions will increase the size of the menu item. + The Chrome extension contextMenus API was taken as a reference. + https://developer.chrome.com/extensions/contextMenus + * - the items with icons and checkable items cannot coexist on the same menu level. The former take precedences over the latter. + * + * @param menu A XML string which describes menu structure. + * @param callback The callback function which is called when a menu item is clicked. The only parameter is the returned ID of clicked menu item. + * + * @description An example menu XML: + * + * + * + * + * + * + * + * + * + * + * + */ +CSInterface.prototype.setContextMenu = function(menu, callback) +{ + if ("string" != typeof menu) + { + return; + } + + window.__adobe_cep__.invokeAsync("setContextMenu", menu, callback); +}; + +/** + * Set context menu by JSON string. + * + * Since 6.0.0 + * + * There are a number of conventions used to communicate what type of menu item to create and how it should be handled. + * - an item without menu ID or menu name is disabled and is not shown. + * - if the item label is "---" (three hyphens) then it is treated as a separator. The menu ID in this case will always be NULL. + * - Checkable attribute takes precedence over Checked attribute. + * - a PNG icon. For optimal display results please supply a 16 x 16px icon as larger dimensions will increase the size of the menu item. + The Chrome extension contextMenus API was taken as a reference. + * - the items with icons and checkable items cannot coexist on the same menu level. The former take precedences over the latter. + https://developer.chrome.com/extensions/contextMenus + * + * @param menu A JSON string which describes menu structure. + * @param callback The callback function which is called when a menu item is clicked. The only parameter is the returned ID of clicked menu item. + * + * @description An example menu JSON: + * + * { + * "menu": [ + * { + * "id": "menuItemId1", + * "label": "testExample1", + * "enabled": true, + * "checkable": true, + * "checked": false, + * "icon": "./image/small_16X16.png" + * }, + * { + * "id": "menuItemId2", + * "label": "testExample2", + * "menu": [ + * { + * "id": "menuItemId2-1", + * "label": "testExample2-1", + * "menu": [ + * { + * "id": "menuItemId2-1-1", + * "label": "testExample2-1-1", + * "enabled": false, + * "checkable": true, + * "checked": true + * } + * ] + * }, + * { + * "id": "menuItemId2-2", + * "label": "testExample2-2", + * "enabled": true, + * "checkable": true, + * "checked": true + * } + * ] + * }, + * { + * "label": "---" + * }, + * { + * "id": "menuItemId3", + * "label": "testExample3", + * "enabled": false, + * "checkable": true, + * "checked": false + * } + * ] + * } + * + */ +CSInterface.prototype.setContextMenuByJSON = function(menu, callback) +{ + if ("string" != typeof menu) + { + return; + } + + window.__adobe_cep__.invokeAsync("setContextMenuByJSON", menu, callback); +}; + +/** + * Updates a context menu item by setting the enabled and selection status. + * + * Since 5.2.0 + * + * @param menuItemID The menu item ID. + * @param enabled True to enable the item, false to disable it (gray it out). + * @param checked True to select the item, false to deselect it. + */ +CSInterface.prototype.updateContextMenuItem = function(menuItemID, enabled, checked) +{ + var itemStatus = new ContextMenuItemStatus(menuItemID, enabled, checked); + ret = window.__adobe_cep__.invokeSync("updateContextMenuItem", JSON.stringify(itemStatus)); +}; + +/** + * Get the visibility status of an extension window. + * + * Since 6.0.0 + * + * @return true if the extension window is visible; false if the extension window is hidden. + */ +CSInterface.prototype.isWindowVisible = function() +{ + return window.__adobe_cep__.invokeSync("isWindowVisible", ""); +}; + +/** + * Resize extension's content to the specified dimensions. + * 1. Works with modal and modeless extensions in all Adobe products. + * 2. Extension's manifest min/max size constraints apply and take precedence. + * 3. For panel extensions + * 3.1 This works in all Adobe products except: + * * Premiere Pro + * * Prelude + * * After Effects + * 3.2 When the panel is in certain states (especially when being docked), + * it will not change to the desired dimensions even when the + * specified size satisfies min/max constraints. + * + * Since 6.0.0 + * + * @param width The new width + * @param height The new height + */ +CSInterface.prototype.resizeContent = function(width, height) +{ + window.__adobe_cep__.resizeContent(width, height); +}; + +/** + * Register the invalid certificate callback for an extension. + * This callback will be triggered when the extension tries to access the web site that contains the invalid certificate on the main frame. + * But if the extension does not call this function and tries to access the web site containing the invalid certificate, a default error page will be shown. + * + * Since 6.1.0 + * + * @param callback the callback function + */ +CSInterface.prototype.registerInvalidCertificateCallback = function(callback) +{ + return window.__adobe_cep__.registerInvalidCertificateCallback(callback); +}; + +/** + * Register an interest in some key events to prevent them from being sent to the host application. + * + * This function works with modeless extensions and panel extensions. + * Generally all the key events will be sent to the host application for these two extensions if the current focused element + * is not text input or dropdown, + * If you want to intercept some key events and want them to be handled in the extension, please call this function + * in advance to prevent them being sent to the host application. + * + * Since 6.1.0 + * + * @param keyEventsInterest A JSON string describing those key events you are interested in. A null object or + an empty string will lead to removing the interest + * + * This JSON string should be an array, each object has following keys: + * + * keyCode: [Required] represents an OS system dependent virtual key code identifying + * the unmodified value of the pressed key. + * ctrlKey: [optional] a Boolean that indicates if the control key was pressed (true) or not (false) when the event occurred. + * altKey: [optional] a Boolean that indicates if the alt key was pressed (true) or not (false) when the event occurred. + * shiftKey: [optional] a Boolean that indicates if the shift key was pressed (true) or not (false) when the event occurred. + * metaKey: [optional] (Mac Only) a Boolean that indicates if the Meta key was pressed (true) or not (false) when the event occurred. + * On Macintosh keyboards, this is the command key. To detect Windows key on Windows, please use keyCode instead. + * An example JSON string: + * + * [ + * { + * "keyCode": 48 + * }, + * { + * "keyCode": 123, + * "ctrlKey": true + * }, + * { + * "keyCode": 123, + * "ctrlKey": true, + * "metaKey": true + * } + * ] + * + */ +CSInterface.prototype.registerKeyEventsInterest = function(keyEventsInterest) +{ + return window.__adobe_cep__.registerKeyEventsInterest(keyEventsInterest); +}; + +/** + * Set the title of the extension window. + * This function works with modal and modeless extensions in all Adobe products, and panel extensions in Photoshop, InDesign, InCopy, Illustrator, Flash Pro and Dreamweaver. + * + * Since 6.1.0 + * + * @param title The window title. + */ +CSInterface.prototype.setWindowTitle = function(title) +{ + window.__adobe_cep__.invokeSync("setWindowTitle", title); +}; + +/** + * Get the title of the extension window. + * This function works with modal and modeless extensions in all Adobe products, and panel extensions in Photoshop, InDesign, InCopy, Illustrator, Flash Pro and Dreamweaver. + * + * Since 6.1.0 + * + * @return The window title. + */ +CSInterface.prototype.getWindowTitle = function() +{ + return window.__adobe_cep__.invokeSync("getWindowTitle", ""); +}; diff --git a/pype/premiere/extensions/com.pype.rename/lib/Vulcan.js b/pype/premiere/extensions/com.pype.rename/lib/Vulcan.js new file mode 100644 index 0000000000..10db662fd3 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/lib/Vulcan.js @@ -0,0 +1,459 @@ +/************************************************************************************************** +* +* ADOBE SYSTEMS INCORPORATED +* Copyright 2013 Adobe Systems Incorporated +* All Rights Reserved. +* +* NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the +* terms of the Adobe license agreement accompanying it. If you have received this file from a +* source other than Adobe, then your use, modification, or distribution of it requires the prior +* written permission of Adobe. +* +**************************************************************************************************/ + +/** Vulcan - v9.2.0 */ + +/** + * @class Vulcan + * + * The singleton instance, VulcanInterface, provides an interface + * to the Vulcan. Allows you to launch CC applications + * and discover information about them. + */ +function Vulcan() +{ +} + +/** + * Gets all available application specifiers on the local machine. + * + * @return The array of all available application specifiers. + */ +Vulcan.prototype.getTargetSpecifiers = function() +{ + var params = {}; + return JSON.parse(window.__adobe_cep__.invokeSync("vulcanGetTargetSpecifiers", JSON.stringify(params))); +}; + +/** + * Launches a CC application on the local machine, if it is not already running. + * + * @param targetSpecifier The application specifier; for example "indesign". + * + * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version + * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you + * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may + * receive wrong result. + * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". + * + * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. + * @param focus True to launch in foreground, or false to launch in the background. + * @param cmdLine Optional, command-line parameters to supply to the launch command. + * @return True if the app can be launched, false otherwise. + */ +Vulcan.prototype.launchApp = function(targetSpecifier, focus, cmdLine) +{ + if(!requiredParamsValid(targetSpecifier)) + { + return false; + } + + var params = {}; + params.targetSpecifier = targetSpecifier; + params.focus = focus ? "true" : "false"; + params.cmdLine = requiredParamsValid(cmdLine) ? cmdLine : ""; + + return JSON.parse(window.__adobe_cep__.invokeSync("vulcanLaunchApp", JSON.stringify(params))).result; +}; + +/** + * Checks whether a CC application is running on the local machine. + * + * @param targetSpecifier The application specifier; for example "indesign". + * + * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version + * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you + * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may + * receive wrong result. + * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". + * + * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. + * @return True if the app is running, false otherwise. + */ +Vulcan.prototype.isAppRunning = function(targetSpecifier) +{ + if(!requiredParamsValid(targetSpecifier)) + { + return false; + } + + var params = {}; + params.targetSpecifier = targetSpecifier; + + return JSON.parse(window.__adobe_cep__.invokeSync("vulcanIsAppRunning", JSON.stringify(params))).result; +}; + +/** + * Checks whether a CC application is installed on the local machine. + * + * @param targetSpecifier The application specifier; for example "indesign". + * + * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version + * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you + * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may + * receive wrong result. + * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". + * + * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. + * @return True if the app is installed, false otherwise. + */ +Vulcan.prototype.isAppInstalled = function(targetSpecifier) +{ + if(!requiredParamsValid(targetSpecifier)) + { + return false; + } + + var params = {}; + params.targetSpecifier = targetSpecifier; + + return JSON.parse(window.__adobe_cep__.invokeSync("vulcanIsAppInstalled", JSON.stringify(params))).result; +}; + +/** + * Retrieves the local install path of a CC application. + * + * @param targetSpecifier The application specifier; for example "indesign". + * + * Note: In Windows 7 64-bit or Windows 8 64-bit system, some target applications (like Photoshop and Illustrator) have both 32-bit version + * and 64-bit version. Therefore, we need to specify the version by this parameter with "photoshop-70.032" or "photoshop-70.064". If you + * installed Photoshop 32-bit and 64-bit on one Windows 64-bit system and invoke this interface with parameter "photoshop-70.032", you may + * receive wrong result. + * The specifiers for Illustrator is "illustrator-17.032", "illustrator-17.064", "illustrator-17" and "illustrator". + * + * In other platforms there is no such issue, so we can use "photoshop" or "photoshop-70" as specifier. + * @return The path string if the application is found, "" otherwise. + */ +Vulcan.prototype.getAppPath = function(targetSpecifier) +{ + if(!requiredParamsValid(targetSpecifier)) + { + return ""; + } + + var params = {}; + params.targetSpecifier = targetSpecifier; + + return JSON.parse(window.__adobe_cep__.invokeSync("vulcanGetAppPath", JSON.stringify(params))).result; +}; + +/** + * Registers a message listener callback function for a Vulcan message. + * + * @param type The message type. + * @param callback The callback function that handles the message. + * Takes one argument, the message object. + * @param obj Optional, the object containing the callback method, if any. + * Default is null. + */ +Vulcan.prototype.addMessageListener = function(type, callback, obj) +{ + if(!requiredParamsValid(type, callback) || !strStartsWith(type, VulcanMessage.TYPE_PREFIX)) + { + return; + } + + var params = {}; + params.type = type; + + window.__adobe_cep__.invokeAsync("vulcanAddMessageListener", JSON.stringify(params), callback, obj); +}; + +/** + * Removes a registered message listener callback function for a Vulcan message. + * + * @param type The message type. + * @param callback The callback function that was registered. + * Takes one argument, the message object. + * @param obj Optional, the object containing the callback method, if any. + * Default is null. + */ +Vulcan.prototype.removeMessageListener = function(type, callback, obj) +{ + if(!requiredParamsValid(type, callback) || !strStartsWith(type, VulcanMessage.TYPE_PREFIX)) + { + return; + } + + var params = {}; + params.type = type; + + window.__adobe_cep__.invokeAsync("vulcanRemoveMessageListener", JSON.stringify(params), callback, obj); +}; + +/** + * Dispatches a Vulcan message. + * + * @param vulcanMessage The message object. + */ +Vulcan.prototype.dispatchMessage = function(vulcanMessage) +{ + if(!requiredParamsValid(vulcanMessage) || !strStartsWith(vulcanMessage.type, VulcanMessage.TYPE_PREFIX)) + { + return; + } + + var params = {}; + var message = new VulcanMessage(vulcanMessage.type); + message.initialize(vulcanMessage); + params.vulcanMessage = message; + + window.__adobe_cep__.invokeSync("vulcanDispatchMessage", JSON.stringify(params)); +}; + +/** + * Retrieves the message payload of a Vulcan message for the registered message listener callback function. + * + * @param vulcanMessage The message object. + * @return A string containing the message payload. + */ +Vulcan.prototype.getPayload = function(vulcanMessage) +{ + if(!requiredParamsValid(vulcanMessage) || !strStartsWith(vulcanMessage.type, VulcanMessage.TYPE_PREFIX)) + { + return null; + } + + var message = new VulcanMessage(vulcanMessage.type); + message.initialize(vulcanMessage); + return message.getPayload(); +}; + +/** + * Gets all available endpoints of the running Vulcan-enabled applications. + * + * Since 7.0.0 + * + * @return The array of all available endpoints. + * An example endpoint string: + * + * PHXS + * 16.1.0 + * + */ +Vulcan.prototype.getEndPoints = function() +{ + var params = {}; + return JSON.parse(window.__adobe_cep__.invokeSync("vulcanGetEndPoints", JSON.stringify(params))); +}; + +/** + * Gets the endpoint for itself. + * + * Since 7.0.0 + * + * @return The endpoint string for itself. + */ +Vulcan.prototype.getSelfEndPoint = function() +{ + var params = {}; + return window.__adobe_cep__.invokeSync("vulcanGetSelfEndPoint", JSON.stringify(params)); +}; + +/** Singleton instance of Vulcan **/ +var VulcanInterface = new Vulcan(); + +//--------------------------------- Vulcan Message ------------------------------ + +/** + * @class VulcanMessage + * Message type for sending messages between host applications. + * A message of this type can be sent to the designated destination + * when appId and appVersion are provided and valid. Otherwise, + * the message is broadcast to all running Vulcan-enabled applications. + * + * To send a message between extensions running within one + * application, use the CSEvent type in CSInterface.js. + * + * @param type The message type. + * @param appId The peer appId. + * @param appVersion The peer appVersion. + * + */ +function VulcanMessage(type, appId, appVersion) +{ + this.type = type; + this.scope = VulcanMessage.SCOPE_SUITE; + this.appId = requiredParamsValid(appId) ? appId : VulcanMessage.DEFAULT_APP_ID; + this.appVersion = requiredParamsValid(appVersion) ? appVersion : VulcanMessage.DEFAULT_APP_VERSION; + this.data = VulcanMessage.DEFAULT_DATA; +} + +VulcanMessage.TYPE_PREFIX = "vulcan.SuiteMessage."; +VulcanMessage.SCOPE_SUITE = "GLOBAL"; +VulcanMessage.DEFAULT_APP_ID = "UNKNOWN"; +VulcanMessage.DEFAULT_APP_VERSION = "UNKNOWN"; +VulcanMessage.DEFAULT_DATA = ""; +VulcanMessage.dataTemplate = "{0}"; +VulcanMessage.payloadTemplate = "{0}"; + +/** + * Initializes this message instance. + * + * @param message A \c message instance to use for initialization. + */ +VulcanMessage.prototype.initialize = function(message) +{ + this.type = message.type; + this.scope = message.scope; + this.appId = message.appId; + this.appVersion = message.appVersion; + this.data = message.data; +}; + +/** + * Retrieves the message data. + * + * @return A data string in XML format. + */ +VulcanMessage.prototype.xmlData = function() +{ + if(this.data === undefined) + { + var str = ""; + str = String.format(VulcanMessage.payloadTemplate, str); + this.data = String.format(VulcanMessage.dataTemplate, str); + } + return this.data; +}; + +/** + * Sets the message payload of this message. + * + * @param payload A string containing the message payload. + */ +VulcanMessage.prototype.setPayload = function(payload) +{ + var str = cep.encoding.convertion.utf8_to_b64(payload); + str = String.format(VulcanMessage.payloadTemplate, str); + this.data = String.format(VulcanMessage.dataTemplate, str); +}; + +/** + * Retrieves the message payload of this message. + * + * @return A string containing the message payload. + */ +VulcanMessage.prototype.getPayload = function() +{ + var str = GetValueByKey(this.data, "payload"); + if(str !== null) + { + return cep.encoding.convertion.b64_to_utf8(str); + } + return null; +}; + +/** + * Converts the properties of this instance to a string. + * + * @return The string version of this instance. + */ +VulcanMessage.prototype.toString = function() +{ + var str = "type=" + this.type; + str += ", scope=" + this.scope; + str += ", appId=" + this.appId; + str += ", appVersion=" + this.appVersion; + str += ", data=" + this.xmlData(); + return str; +}; + +//--------------------------------------- Util -------------------------------- + +/** + * Formats a string based on a template. + * + * @param src The format template. + * + * @return The formatted string + */ +String.format = function(src) +{ + if (arguments.length === 0) + { + return null; + } + + var args = Array.prototype.slice.call(arguments, 1); + return src.replace(/\{(\d+)\}/g, function(m, i){ + return args[i]; + }); +}; + +/** + * Retrieves the content of an XML element. + * + * @param xmlStr The XML string. + * @param key The name of the tag. + * + * @return The content of the tag, or the empty string + * if such tag is not found or the tag has no content. + */ +function GetValueByKey(xmlStr, key) +{ + if(window.DOMParser) + { + var parser = new window.DOMParser(); + try + { + var xmlDoc = parser.parseFromString(xmlStr, "text/xml"); + var node = xmlDoc.getElementsByTagName(key)[0]; + if(node && node.childNodes[0]) + { + return node.childNodes[0].nodeValue; + } + } + catch(e) + { + //log the error + } + } + return ""; +} + +/** + * Reports whether required parameters are valid. + * + * @return True if all required parameters are valid, + * false if any of the required parameters are invalid. + */ +function requiredParamsValid() +{ + for(var i = 0; i < arguments.length; i++) + { + var argument = arguments[i]; + if(argument === undefined || argument === null) + { + return false; + } + } + return true; +} + +/** + * Reports whether a string has a given prefix. + * + * @param str The target string. + * @param prefix The specific prefix string. + * + * @return True if the string has the prefix, false if not. + */ +function strStartsWith(str, prefix) +{ + if(typeof str != "string") + { + return false; + } + return str.indexOf(prefix) === 0; +} diff --git a/pype/premiere/extensions/com.pype.rename/lib/jquery-1.9.1.js b/pype/premiere/extensions/com.pype.rename/lib/jquery-1.9.1.js new file mode 100644 index 0000000000..e2c203fe97 --- /dev/null +++ b/pype/premiere/extensions/com.pype.rename/lib/jquery-1.9.1.js @@ -0,0 +1,9597 @@ +/*! + * jQuery JavaScript Library v1.9.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-2-4 + */ +(function( window, undefined ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; +var + // The deferred used on DOM ready + readyList, + + // A central reference to the root jQuery(document) + rootjQuery, + + // Support: IE<9 + // For `typeof node.method` instead of `node.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.9.1", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, all, a, + input, select, fragment, + opt, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: div.firstChild.nodeType === 3, + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: a.getAttribute("href") === "/a", + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + checkOn: !!input.value, + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: document.compatMode === "CSS1Compat", + + // Will be defined later + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== core_strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})(); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var i, l, thisCache, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.slice(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + // Try to fetch any internally stored data first + return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + } + + this.each(function() { + jQuery.data( this, key, value ); + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + hooks.cur = fn; + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var ret, hooks, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, notxml, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + // In IE9+, Flash objects don't have .getAttribute (#12945) + // Support: IE9+ + if ( typeof elem.getAttribute !== core_strundefined ) { + ret = elem.getAttribute( name ); + } + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( rboolean.test( name ) ) { + // Set corresponding property to false for boolean attributes + // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 + if ( !getSetAttribute && ruseDefault.test( name ) ) { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } else { + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + var + // Use .prop to determine if this attribute is understood as boolean + prop = jQuery.prop( elem, name ), + + // Fetch it accordingly + attr = typeof prop === "boolean" && elem.getAttribute( name ), + detail = typeof prop === "boolean" ? + + getSetInput && getSetAttribute ? + attr != null : + // oldIE fabricates an empty string for missing boolean attributes + // and conflates checked/selected into attroperties + ruseDefault.test( name ) ? + elem[ jQuery.camelCase( "default-" + name ) ] : + !!attr : + + // fetch an attribute node for properties not recognized as boolean + elem.getAttributeNode( name ); + + return detail && detail.value !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; + +// fix oldIE value attroperty +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return jQuery.nodeName( elem, "input" ) ? + + // Ignore the value *property* by using defaultValue + elem.defaultValue : + + ret && ret.specified ? ret.value : undefined; + }, + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret == null ? undefined : ret; + } + }); + }); + + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + event.isTrigger = true; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur != this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + } + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== document.activeElement && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === document.activeElement && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === core_strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var i, + cachedruns, + Expr, + getText, + isXML, + compile, + hasDuplicate, + outermostContext, + + // Local document vars + setDocument, + document, + docElem, + documentIsXML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + sortOrder, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + support = {}, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Array methods + arr = [], + pop = arr.pop, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rsibling = /[\x20\t\r\n\f]*[+~]/, + + rnative = /^[^{]+\{\s*\[native code/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, + funescape = function( _, escaped ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + return high !== high ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Use a stripped-down slice if we can't use a native one +try { + slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + while ( (elem = this[i++]) ) { + results.push( elem ); + } + return results; + }; +} + +/** + * For feature detection + * @param {Function} fn The function to test for native support + */ +function isNative( fn ) { + return rnative.test( fn + "" ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var cache, + keys = []; + + return (cache = function( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + }); +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( !documentIsXML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getByClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + + // QSA path + if ( support.qsa && !rbuggyQSA.test(selector) ) { + old = true; + nid = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsXML = isXML( doc ); + + // Check if getElementsByTagName("*") returns only elements + support.tagNameNoComments = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if attributes should be retrieved by attribute nodes + support.attributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }); + + // Check if getElementsByClassName can be trusted + support.getByClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }); + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + support.getByName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = doc.getElementsByName && + // buggy browsers will return fewer than the correct 2 + doc.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + doc.getElementsByName( expando + 0 ).length; + support.getIdNotName = !doc.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + + // IE6/7 return modified attributes + Expr.attrHandle = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }) ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }; + + // ID find and filter + if ( support.getIdNotName ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && !documentIsXML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && !documentIsXML ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.tagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Name + Expr.find["NAME"] = support.getByName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }; + + // Class + Expr.find["CLASS"] = support.getByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) { + return context.getElementsByClassName( className ); + } + }; + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21), + // no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ]; + + if ( (support.qsa = isNative(doc.querySelectorAll)) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE8 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = ""; + if ( div.querySelectorAll("[i^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = new RegExp( rbuggyMatches.join("|") ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = isNative(docElem.contains) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + var compare; + + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) { + if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) { + if ( a === doc || contains( preferredDoc, a ) ) { + return -1; + } + if ( b === doc || contains( preferredDoc, b ) ) { + return 1; + } + return 0; + } + return compare & 4 ? -1 : 1; + } + + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + // Always assume the presence of duplicates if sort doesn't + // pass them to our comparison function (as in Google Chrome). + hasDuplicate = false; + [0, 0].sort( sortOrder ); + support.detectDuplicates = hasDuplicate; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyQSA always contains :focus, so no need for an existence check + if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + var val; + + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + if ( !documentIsXML ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( documentIsXML || support.attributes ) { + return elem.getAttribute( name ); + } + return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ? + name : + val && val.specified ? val.value : null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[4] ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + + nodeName = nodeName.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifider + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsXML ? + elem.getAttribute("xml:lang") || elem.getAttribute("lang") : + elem.lang) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push( { + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !documentIsXML && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + documentIsXML, + results, + rsibling.test( selector ) + ); + return results; +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Easy API for creating new setFilters +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Initialize with the default document +setDocument(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, ret, self, + len = this.length; + + if ( typeof selector !== "string" ) { + self = this; + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + ret = []; + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, this[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true) ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, false, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, false, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length > 0 ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + var isFunc = jQuery.isFunction( value ); + + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( !isFunc && typeof value !== "string" ) { + value = jQuery( value ).not( this ).detach(); + } + + return this.domManip( [ value ], true, function( elem ) { + var next = this.nextSibling, + parent = this.parentNode; + + if ( parent ) { + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + }); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, table ? self.html() : undefined ); + } + self.domManip( args, table, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + node, + i + ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery.ajax({ + url: node.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + var attr = elem.getAttributeNode("type"); + elem.type = ( attr && attr.specified ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== core_strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + } +}); +var iframe, getStyles, curCSS, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var len, styles, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + var bool = typeof state === "boolean"; + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery("