From ea4a382d3359d1a6a3d2abcb9adfdaf45d87e0a0 Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Mon, 12 Mar 2018 14:55:08 -0600 Subject: [PATCH 1/9] Create javascript basics challenge with everything set up, my rectangles test all passes for all methods, rectangles js file has some refactored logic.. --- node_modules/.bin/_mocha | 1 + node_modules/.bin/cake | 1 + node_modules/.bin/coffee | 1 + node_modules/.bin/has-ansi | 1 + node_modules/.bin/he | 1 + node_modules/.bin/mkdirp | 1 + node_modules/.bin/mocha | 1 + node_modules/.bin/pryjs | 1 + node_modules/.bin/strip-ansi | 1 + node_modules/ansi-regex/index.js | 4 + node_modules/ansi-regex/package.json | 84 + node_modules/ansi-regex/readme.md | 33 + node_modules/ansi-styles/index.js | 40 + node_modules/ansi-styles/package.json | 78 + node_modules/ansi-styles/readme.md | 70 + node_modules/assertion-error/History.md | 24 + node_modules/assertion-error/README.md | 41 + node_modules/assertion-error/index.d.ts | 11 + node_modules/assertion-error/index.js | 116 + node_modules/assertion-error/package.json | 62 + node_modules/balanced-match/.npmignore | 5 + node_modules/balanced-match/LICENSE.md | 21 + node_modules/balanced-match/README.md | 91 + node_modules/balanced-match/index.js | 59 + node_modules/balanced-match/package.json | 77 + node_modules/bindings/README.md | 97 + node_modules/bindings/bindings.js | 166 + node_modules/bindings/package.json | 54 + node_modules/bl/.jshintrc | 59 + node_modules/bl/.npmignore | 1 + node_modules/bl/.travis.yml | 11 + node_modules/bl/LICENSE | 39 + node_modules/bl/README.md | 165 + node_modules/bl/bl.js | 157 + node_modules/bl/package.json | 60 + node_modules/bl/test.js | 356 + node_modules/brace-expansion/LICENSE | 21 + node_modules/brace-expansion/README.md | 129 + node_modules/brace-expansion/index.js | 201 + node_modules/brace-expansion/package.json | 75 + node_modules/browser-stdout/LICENSE | 5 + node_modules/browser-stdout/README.md | 40 + node_modules/browser-stdout/index.js | 25 + node_modules/browser-stdout/package.json | 46 + node_modules/chai/.npmignore | 14 + node_modules/chai/CODEOWNERS | 1 + node_modules/chai/CODE_OF_CONDUCT.md | 58 + node_modules/chai/CONTRIBUTING.md | 218 + node_modules/chai/History.md | 1059 ++ node_modules/chai/LICENSE | 21 + node_modules/chai/README.md | 212 + node_modules/chai/ReleaseNotes.md | 737 + node_modules/chai/chai.js | 10707 +++++++++++ node_modules/chai/index.js | 1 + node_modules/chai/karma.conf.js | 28 + node_modules/chai/karma.sauce.js | 41 + node_modules/chai/lib/chai.js | 92 + node_modules/chai/lib/chai/assertion.js | 165 + node_modules/chai/lib/chai/config.js | 94 + node_modules/chai/lib/chai/core/assertions.js | 3729 ++++ .../chai/lib/chai/interface/assert.js | 3098 ++++ .../chai/lib/chai/interface/expect.js | 34 + .../chai/lib/chai/interface/should.js | 204 + .../chai/lib/chai/utils/addChainableMethod.js | 152 + .../chai/lib/chai/utils/addLengthGuard.js | 62 + node_modules/chai/lib/chai/utils/addMethod.js | 68 + .../chai/lib/chai/utils/addProperty.js | 72 + .../chai/lib/chai/utils/compareByInspect.js | 31 + .../chai/lib/chai/utils/expectTypes.js | 51 + node_modules/chai/lib/chai/utils/flag.js | 33 + node_modules/chai/lib/chai/utils/getActual.js | 20 + .../lib/chai/utils/getEnumerableProperties.js | 26 + .../chai/lib/chai/utils/getMessage.js | 51 + .../chai/utils/getOwnEnumerableProperties.js | 29 + .../utils/getOwnEnumerablePropertySymbols.js | 27 + .../chai/lib/chai/utils/getProperties.js | 36 + node_modules/chai/lib/chai/utils/index.js | 172 + node_modules/chai/lib/chai/utils/inspect.js | 383 + node_modules/chai/lib/chai/utils/isNaN.js | 26 + .../chai/lib/chai/utils/isProxyEnabled.js | 24 + .../chai/lib/chai/utils/objDisplay.js | 50 + .../chai/utils/overwriteChainableMethod.js | 69 + .../chai/lib/chai/utils/overwriteMethod.js | 92 + .../chai/lib/chai/utils/overwriteProperty.js | 92 + node_modules/chai/lib/chai/utils/proxify.js | 125 + node_modules/chai/lib/chai/utils/test.js | 28 + .../chai/lib/chai/utils/transferFlags.js | 45 + node_modules/chai/package.json | 96 + node_modules/chai/register-assert.js | 1 + node_modules/chai/register-expect.js | 1 + node_modules/chai/register-should.js | 1 + node_modules/chai/sauce.browsers.js | 111 + node_modules/chalk/index.js | 95 + .../chalk/node_modules/.bin/supports-color | 1 + .../chalk/node_modules/supports-color/cli.js | 28 + .../node_modules/supports-color/index.js | 32 + .../node_modules/supports-color/package.json | 82 + .../node_modules/supports-color/readme.md | 44 + node_modules/chalk/package.json | 92 + node_modules/chalk/readme.md | 175 + node_modules/check-error/LICENSE | 19 + node_modules/check-error/README.md | 207 + node_modules/check-error/check-error.js | 176 + node_modules/check-error/index.js | 172 + node_modules/check-error/package.json | 130 + node_modules/coffee-script/LICENSE | 22 + node_modules/coffee-script/README.md | 57 + node_modules/coffee-script/bin/cake | 18 + node_modules/coffee-script/bin/coffee | 18 + .../lib/coffee-script/browser.js | 132 + .../coffee-script/lib/coffee-script/cake.js | 114 + .../lib/coffee-script/coffee-script.js | 426 + .../lib/coffee-script/command.js | 610 + .../lib/coffee-script/grammar.js | 816 + .../lib/coffee-script/helpers.js | 249 + .../coffee-script/lib/coffee-script/index.js | 11 + .../coffee-script/lib/coffee-script/lexer.js | 1166 ++ .../coffee-script/lib/coffee-script/nodes.js | 3899 ++++ .../lib/coffee-script/optparse.js | 139 + .../coffee-script/lib/coffee-script/parser.js | 891 + .../lib/coffee-script/register.js | 66 + .../coffee-script/lib/coffee-script/repl.js | 203 + .../lib/coffee-script/rewriter.js | 537 + .../coffee-script/lib/coffee-script/scope.js | 165 + .../lib/coffee-script/sourcemap.js | 161 + node_modules/coffee-script/package.json | 77 + node_modules/coffee-script/register.js | 1 + node_modules/coffee-script/repl.js | 1 + node_modules/commander/History.md | 298 + node_modules/commander/LICENSE | 22 + node_modules/commander/Readme.md | 351 + node_modules/commander/index.js | 1137 ++ node_modules/commander/package.json | 61 + node_modules/concat-map/.travis.yml | 4 + node_modules/concat-map/LICENSE | 18 + node_modules/concat-map/README.markdown | 62 + node_modules/concat-map/example/map.js | 6 + node_modules/concat-map/index.js | 13 + node_modules/concat-map/package.json | 88 + node_modules/concat-map/test/map.js | 39 + node_modules/core-util-is/LICENSE | 19 + node_modules/core-util-is/README.md | 3 + node_modules/core-util-is/float.patch | 604 + node_modules/core-util-is/lib/util.js | 107 + node_modules/core-util-is/package.json | 63 + node_modules/core-util-is/test.js | 68 + node_modules/deasync/README.md | 112 + .../bin/darwin-x64-node-0.10/deasync.node | Bin 0 -> 10344 bytes .../bin/darwin-x64-node-0.11/deasync.node | Bin 0 -> 10808 bytes .../bin/darwin-x64-node-0.12/deasync.node | Bin 0 -> 10848 bytes .../bin/darwin-x64-node-4/deasync.node | Bin 0 -> 11920 bytes .../bin/darwin-x64-node-5/deasync.node | Bin 0 -> 11920 bytes .../bin/darwin-x64-node-6/deasync.node | Bin 0 -> 13032 bytes .../bin/darwin-x64-node-7/deasync.node | Bin 0 -> 13088 bytes .../bin/darwin-x64-node-8/deasync.node | Bin 0 -> 13112 bytes .../bin/darwin-x64-node-9/deasync.node | Bin 0 -> 13104 bytes .../bin/linux-ia32-node-0.10/deasync.node | Bin 0 -> 7672 bytes .../bin/linux-ia32-node-0.11/deasync.node | Bin 0 -> 7914 bytes .../bin/linux-ia32-node-0.12/deasync.node | Bin 0 -> 7914 bytes .../bin/linux-ia32-node-4/deasync.node | Bin 0 -> 12551 bytes .../bin/linux-ia32-node-5/deasync.node | Bin 0 -> 12551 bytes .../bin/linux-ia32-node-6/deasync.node | Bin 0 -> 12551 bytes .../bin/linux-ia32-node-7/deasync.node | Bin 0 -> 12832 bytes .../bin/linux-ia32-node-8/deasync.node | Bin 0 -> 12832 bytes .../bin/linux-ia32-node-9/deasync.node | Bin 0 -> 12832 bytes .../bin/linux-x64-node-0.10/deasync.node | Bin 0 -> 9580 bytes .../bin/linux-x64-node-0.11/deasync.node | Bin 0 -> 13407 bytes .../bin/linux-x64-node-0.12/deasync.node | Bin 0 -> 13384 bytes .../deasync/bin/linux-x64-node-4/deasync.node | Bin 0 -> 13989 bytes .../deasync/bin/linux-x64-node-5/deasync.node | Bin 0 -> 13989 bytes .../deasync/bin/linux-x64-node-6/deasync.node | Bin 0 -> 13989 bytes .../deasync/bin/linux-x64-node-7/deasync.node | Bin 0 -> 14014 bytes .../deasync/bin/linux-x64-node-8/deasync.node | Bin 0 -> 14014 bytes .../deasync/bin/linux-x64-node-9/deasync.node | Bin 0 -> 14014 bytes .../bin/win32-ia32-node-0.10/deasync.node | Bin 0 -> 33792 bytes .../bin/win32-ia32-node-0.11/deasync.node | Bin 0 -> 50176 bytes .../bin/win32-ia32-node-0.12/deasync.node | Bin 0 -> 50176 bytes .../bin/win32-ia32-node-4/deasync.node | Bin 0 -> 106496 bytes .../bin/win32-ia32-node-5/deasync.node | Bin 0 -> 105984 bytes .../bin/win32-ia32-node-6/deasync.node | Bin 0 -> 101376 bytes .../bin/win32-ia32-node-7/deasync.node | Bin 0 -> 75776 bytes .../bin/win32-ia32-node-8/deasync.node | Bin 0 -> 75776 bytes .../bin/win32-ia32-node-9/deasync.node | Bin 0 -> 75776 bytes .../bin/win32-x64-node-0.10/deasync.node | Bin 0 -> 82432 bytes .../bin/win32-x64-node-0.11/deasync.node | Bin 0 -> 107008 bytes .../bin/win32-x64-node-0.12/deasync.node | Bin 0 -> 107008 bytes .../deasync/bin/win32-x64-node-4/deasync.node | Bin 0 -> 120832 bytes .../deasync/bin/win32-x64-node-5/deasync.node | Bin 0 -> 120320 bytes .../deasync/bin/win32-x64-node-6/deasync.node | Bin 0 -> 117248 bytes .../deasync/bin/win32-x64-node-7/deasync.node | Bin 0 -> 89600 bytes .../deasync/bin/win32-x64-node-8/deasync.node | Bin 0 -> 90112 bytes .../deasync/bin/win32-x64-node-9/deasync.node | Bin 0 -> 91648 bytes node_modules/deasync/binding.gyp | 11 + node_modules/deasync/build.js | 120 + node_modules/deasync/index.js | 76 + node_modules/deasync/package.json | 67 + node_modules/deasync/quick-test.js | 7 + node_modules/deasync/src/deasync.cc | 17 + node_modules/deasync/test.js | 31 + node_modules/debug/.coveralls.yml | 1 + node_modules/debug/.eslintrc | 14 + node_modules/debug/.npmignore | 9 + node_modules/debug/.travis.yml | 20 + node_modules/debug/CHANGELOG.md | 395 + node_modules/debug/LICENSE | 19 + node_modules/debug/Makefile | 58 + node_modules/debug/README.md | 368 + node_modules/debug/karma.conf.js | 70 + node_modules/debug/node.js | 1 + node_modules/debug/package.json | 82 + node_modules/debug/src/browser.js | 195 + node_modules/debug/src/debug.js | 225 + node_modules/debug/src/index.js | 10 + node_modules/debug/src/node.js | 186 + node_modules/deep-eql/LICENSE | 19 + node_modules/deep-eql/README.md | 116 + node_modules/deep-eql/deep-eql.js | 833 + node_modules/deep-eql/index.js | 455 + node_modules/deep-eql/package.json | 131 + node_modules/diff/CONTRIBUTING.md | 39 + node_modules/diff/LICENSE | 31 + node_modules/diff/README.md | 211 + node_modules/diff/dist/diff.js | 1843 ++ node_modules/diff/dist/diff.min.js | 416 + node_modules/diff/lib/convert/dmp.js | 24 + node_modules/diff/lib/convert/xml.js | 35 + node_modules/diff/lib/diff/array.js | 24 + node_modules/diff/lib/diff/base.js | 235 + node_modules/diff/lib/diff/character.js | 17 + node_modules/diff/lib/diff/css.js | 21 + node_modules/diff/lib/diff/json.js | 108 + node_modules/diff/lib/diff/line.js | 50 + node_modules/diff/lib/diff/sentence.js | 21 + node_modules/diff/lib/diff/word.js | 70 + node_modules/diff/lib/index.js | 74 + node_modules/diff/lib/patch/apply.js | 180 + node_modules/diff/lib/patch/create.js | 148 + node_modules/diff/lib/patch/merge.js | 396 + node_modules/diff/lib/patch/parse.js | 147 + node_modules/diff/lib/util/array.js | 27 + .../diff/lib/util/distance-iterator.js | 47 + node_modules/diff/lib/util/params.js | 18 + node_modules/diff/package.json | 97 + node_modules/diff/release-notes.md | 247 + node_modules/diff/runtime.js | 3 + node_modules/diff/yarn.lock | 5729 ++++++ node_modules/escape-string-regexp/index.js | 11 + node_modules/escape-string-regexp/license | 21 + .../escape-string-regexp/package.json | 81 + node_modules/escape-string-regexp/readme.md | 27 + node_modules/fs.realpath/LICENSE | 43 + node_modules/fs.realpath/README.md | 33 + node_modules/fs.realpath/index.js | 66 + node_modules/fs.realpath/old.js | 303 + node_modules/fs.realpath/package.json | 59 + node_modules/get-func-name/LICENSE | 19 + node_modules/get-func-name/README.md | 123 + node_modules/get-func-name/get-func-name.js | 48 + node_modules/get-func-name/index.js | 44 + node_modules/get-func-name/package.json | 133 + node_modules/glob/LICENSE | 15 + node_modules/glob/README.md | 368 + node_modules/glob/changelog.md | 67 + node_modules/glob/common.js | 240 + node_modules/glob/glob.js | 790 + node_modules/glob/package.json | 76 + node_modules/glob/sync.js | 486 + node_modules/growl/.eslintrc.json | 14 + node_modules/growl/.tags | 195 + node_modules/growl/.tags1 | 166 + node_modules/growl/.travis.yml | 21 + node_modules/growl/History.md | 68 + node_modules/growl/Readme.md | 109 + node_modules/growl/lib/growl.js | 341 + node_modules/growl/package.json | 67 + node_modules/growl/test.js | 31 + node_modules/has-ansi/cli.js | 53 + node_modules/has-ansi/index.js | 4 + node_modules/has-ansi/package.json | 89 + node_modules/has-ansi/readme.md | 45 + node_modules/has-flag/index.js | 10 + node_modules/has-flag/license | 21 + node_modules/has-flag/package.json | 93 + node_modules/has-flag/readme.md | 67 + node_modules/he/LICENSE-MIT.txt | 20 + node_modules/he/README.md | 379 + node_modules/he/bin/he | 148 + node_modules/he/he.js | 342 + node_modules/he/man/he.1 | 78 + node_modules/he/package.json | 88 + node_modules/inflight/LICENSE | 15 + node_modules/inflight/README.md | 37 + node_modules/inflight/inflight.js | 54 + node_modules/inflight/package.json | 58 + node_modules/inherits/LICENSE | 16 + node_modules/inherits/README.md | 42 + node_modules/inherits/inherits.js | 7 + node_modules/inherits/inherits_browser.js | 23 + node_modules/inherits/package.json | 61 + node_modules/isarray/README.md | 54 + node_modules/isarray/build/build.js | 209 + node_modules/isarray/component.json | 19 + node_modules/isarray/index.js | 3 + node_modules/isarray/package.json | 58 + node_modules/minimatch/LICENSE | 15 + node_modules/minimatch/README.md | 209 + node_modules/minimatch/minimatch.js | 923 + node_modules/minimatch/package.json | 63 + node_modules/minimist/.travis.yml | 4 + node_modules/minimist/LICENSE | 18 + node_modules/minimist/example/parse.js | 2 + node_modules/minimist/index.js | 187 + node_modules/minimist/package.json | 71 + node_modules/minimist/readme.markdown | 73 + node_modules/minimist/test/dash.js | 24 + node_modules/minimist/test/default_bool.js | 20 + node_modules/minimist/test/dotted.js | 16 + node_modules/minimist/test/long.js | 31 + node_modules/minimist/test/parse.js | 318 + node_modules/minimist/test/parse_modified.js | 9 + node_modules/minimist/test/short.js | 67 + node_modules/minimist/test/whitespace.js | 8 + node_modules/mkdirp/.travis.yml | 8 + 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 | 98 + node_modules/mkdirp/package.json | 62 + node_modules/mkdirp/readme.markdown | 100 + node_modules/mkdirp/test/chmod.js | 41 + node_modules/mkdirp/test/clobber.js | 38 + node_modules/mkdirp/test/mkdirp.js | 28 + node_modules/mkdirp/test/opts_fs.js | 29 + node_modules/mkdirp/test/opts_fs_sync.js | 27 + node_modules/mkdirp/test/perm.js | 32 + node_modules/mkdirp/test/perm_sync.js | 36 + node_modules/mkdirp/test/race.js | 37 + node_modules/mkdirp/test/rel.js | 32 + node_modules/mkdirp/test/return.js | 25 + node_modules/mkdirp/test/return_sync.js | 24 + node_modules/mkdirp/test/root.js | 19 + node_modules/mkdirp/test/sync.js | 32 + node_modules/mkdirp/test/umask.js | 28 + node_modules/mkdirp/test/umask_sync.js | 32 + node_modules/mocha/CHANGELOG.md | 1890 ++ node_modules/mocha/LICENSE | 22 + node_modules/mocha/README.md | 104 + node_modules/mocha/bin/.eslintrc.yml | 3 + node_modules/mocha/bin/_mocha | 592 + node_modules/mocha/bin/mocha | 89 + node_modules/mocha/bin/options.js | 43 + node_modules/mocha/browser-entry.js | 187 + node_modules/mocha/images/error.png | Bin 0 -> 412 bytes node_modules/mocha/images/ok.png | Bin 0 -> 388 bytes node_modules/mocha/index.js | 3 + node_modules/mocha/lib/browser/.eslintrc.yml | 4 + node_modules/mocha/lib/browser/growl.js | 5 + node_modules/mocha/lib/browser/progress.js | 119 + node_modules/mocha/lib/browser/tty.js | 13 + node_modules/mocha/lib/context.js | 99 + node_modules/mocha/lib/hook.js | 48 + node_modules/mocha/lib/interfaces/bdd.js | 115 + node_modules/mocha/lib/interfaces/common.js | 155 + node_modules/mocha/lib/interfaces/exports.js | 63 + node_modules/mocha/lib/interfaces/index.js | 6 + node_modules/mocha/lib/interfaces/qunit.js | 99 + node_modules/mocha/lib/interfaces/tdd.js | 106 + node_modules/mocha/lib/mocha.js | 573 + node_modules/mocha/lib/ms.js | 90 + node_modules/mocha/lib/pending.js | 16 + node_modules/mocha/lib/reporters/base.js | 502 + node_modules/mocha/lib/reporters/doc.js | 64 + node_modules/mocha/lib/reporters/dot.js | 68 + node_modules/mocha/lib/reporters/html.js | 348 + node_modules/mocha/lib/reporters/index.js | 19 + .../mocha/lib/reporters/json-stream.js | 62 + node_modules/mocha/lib/reporters/json.js | 92 + node_modules/mocha/lib/reporters/landing.js | 94 + node_modules/mocha/lib/reporters/list.js | 63 + node_modules/mocha/lib/reporters/markdown.js | 99 + node_modules/mocha/lib/reporters/min.js | 38 + node_modules/mocha/lib/reporters/nyan.js | 263 + node_modules/mocha/lib/reporters/progress.js | 93 + node_modules/mocha/lib/reporters/spec.js | 81 + node_modules/mocha/lib/reporters/tap.js | 70 + node_modules/mocha/lib/reporters/xunit.js | 183 + node_modules/mocha/lib/runnable.js | 419 + node_modules/mocha/lib/runner.js | 982 + node_modules/mocha/lib/suite.js | 414 + node_modules/mocha/lib/template.html | 18 + node_modules/mocha/lib/test.js | 50 + node_modules/mocha/lib/utils.js | 618 + node_modules/mocha/mocha.css | 326 + node_modules/mocha/mocha.js | 15294 ++++++++++++++++ node_modules/mocha/package.json | 1392 ++ node_modules/ms/index.js | 152 + node_modules/ms/license.md | 21 + node_modules/ms/package.json | 69 + node_modules/ms/readme.md | 51 + node_modules/nan/CHANGELOG.md | 485 + node_modules/nan/LICENSE.md | 13 + node_modules/nan/README.md | 456 + node_modules/nan/doc/asyncworker.md | 146 + node_modules/nan/doc/buffers.md | 54 + node_modules/nan/doc/callback.md | 76 + node_modules/nan/doc/converters.md | 41 + node_modules/nan/doc/errors.md | 226 + node_modules/nan/doc/json.md | 62 + node_modules/nan/doc/maybe_types.md | 582 + node_modules/nan/doc/methods.md | 659 + node_modules/nan/doc/new.md | 147 + node_modules/nan/doc/node_misc.md | 121 + node_modules/nan/doc/object_wrappers.md | 263 + node_modules/nan/doc/persistent.md | 295 + node_modules/nan/doc/scopes.md | 73 + node_modules/nan/doc/script.md | 38 + node_modules/nan/doc/string_bytes.md | 62 + node_modules/nan/doc/v8_internals.md | 199 + node_modules/nan/doc/v8_misc.md | 85 + node_modules/nan/include_dirs.js | 1 + node_modules/nan/nan.h | 2657 +++ node_modules/nan/nan_callbacks.h | 88 + node_modules/nan/nan_callbacks_12_inl.h | 512 + node_modules/nan/nan_callbacks_pre_12_inl.h | 520 + node_modules/nan/nan_converters.h | 72 + node_modules/nan/nan_converters_43_inl.h | 48 + node_modules/nan/nan_converters_pre_43_inl.h | 42 + node_modules/nan/nan_implementation_12_inl.h | 399 + .../nan/nan_implementation_pre_12_inl.h | 263 + node_modules/nan/nan_json.h | 166 + node_modules/nan/nan_maybe_43_inl.h | 369 + node_modules/nan/nan_maybe_pre_43_inl.h | 318 + node_modules/nan/nan_new.h | 340 + node_modules/nan/nan_object_wrap.h | 155 + node_modules/nan/nan_persistent_12_inl.h | 132 + node_modules/nan/nan_persistent_pre_12_inl.h | 242 + node_modules/nan/nan_private.h | 73 + node_modules/nan/nan_string_bytes.h | 305 + node_modules/nan/nan_typedarray_contents.h | 90 + node_modules/nan/nan_weak.h | 432 + node_modules/nan/package.json | 97 + node_modules/nan/tools/1to2.js | 412 + node_modules/nan/tools/README.md | 14 + node_modules/nan/tools/package.json | 19 + node_modules/object-keys/.npmignore | 1 + node_modules/object-keys/.travis.yml | 5 + node_modules/object-keys/README.md | 39 + node_modules/object-keys/foreach.js | 40 + node_modules/object-keys/index.js | 2 + node_modules/object-keys/isArguments.js | 16 + node_modules/object-keys/package.json | 77 + node_modules/object-keys/shim.js | 62 + node_modules/object-keys/test/foreach.js | 156 + node_modules/object-keys/test/index.js | 6 + node_modules/object-keys/test/isArguments.js | 10 + node_modules/object-keys/test/shim.js | 134 + node_modules/once/LICENSE | 15 + node_modules/once/README.md | 79 + node_modules/once/once.js | 42 + node_modules/once/package.json | 67 + node_modules/path-is-absolute/index.js | 20 + node_modules/path-is-absolute/license | 21 + node_modules/path-is-absolute/package.json | 75 + node_modules/path-is-absolute/readme.md | 59 + node_modules/pathval/CHANGELOG.md | 18 + node_modules/pathval/LICENSE | 16 + node_modules/pathval/README.md | 145 + node_modules/pathval/index.js | 291 + node_modules/pathval/package.json | 110 + node_modules/pathval/pathval.js | 295 + node_modules/pryjs/.npmignore | 3 + node_modules/pryjs/.travis.yml | 15 + node_modules/pryjs/Gruntfile.coffee | 19 + node_modules/pryjs/LICENSE | 21 + node_modules/pryjs/assets/demo.png | Bin 0 -> 91469 bytes node_modules/pryjs/bin/deploy | 1 + node_modules/pryjs/bin/pryjs | 3 + node_modules/pryjs/build/pry.js | 32 + node_modules/pryjs/build/pry/app.js | 82 + node_modules/pryjs/build/pry/command.js | 87 + .../pryjs/build/pry/commands/continue.js | 31 + node_modules/pryjs/build/pry/commands/help.js | 76 + .../pryjs/build/pry/commands/index.js | 16 + node_modules/pryjs/build/pry/commands/kill.js | 33 + node_modules/pryjs/build/pry/commands/play.js | 40 + .../pryjs/build/pry/commands/version.js | 32 + .../pryjs/build/pry/commands/whereami.js | 43 + node_modules/pryjs/build/pry/commands/wtf.js | 36 + .../pryjs/build/pry/commands/xecute.js | 70 + node_modules/pryjs/build/pry/compiler.js | 50 + node_modules/pryjs/build/pry/file.js | 55 + .../pryjs/build/pry/output/local_output.js | 31 + node_modules/pryjs/build/pry/range.js | 35 + .../pryjs/build/pry/sync_highlight.js | 92 + node_modules/pryjs/build/pry/sync_prompt.js | 159 + node_modules/pryjs/changelog.md | 104 + node_modules/pryjs/code_of_conduct.md | 15 + node_modules/pryjs/docs/.npmignore | 3 + node_modules/pryjs/docs/404.md | 7 + node_modules/pryjs/docs/GEMFILE | 4 + node_modules/pryjs/docs/LICENSE | 21 + node_modules/pryjs/docs/README.md | 14 + node_modules/pryjs/docs/_config.yml | 46 + node_modules/pryjs/docs/_includes/disqus.html | 10 + node_modules/pryjs/docs/_includes/footer.html | 9 + node_modules/pryjs/docs/_includes/head.html | 46 + node_modules/pryjs/docs/_includes/header.html | 24 + node_modules/pryjs/docs/_includes/icons.html | 3 + node_modules/pryjs/docs/_layouts/default.html | 11 + node_modules/pryjs/docs/_layouts/home.html | 14 + node_modules/pryjs/docs/_layouts/page.html | 9 + node_modules/pryjs/docs/_layouts/post.html | 42 + .../pryjs/docs/_sass/base/_global.scss | 123 + .../pryjs/docs/_sass/base/_utility.scss | 35 + .../pryjs/docs/_sass/base/_variables.scss | 30 + .../pryjs/docs/_sass/external/_reset.scss | 427 + .../pryjs/docs/_sass/external/_syntax.scss | 63 + .../pryjs/docs/_sass/includes/_footer.scss | 8 + .../pryjs/docs/_sass/includes/_header.scss | 86 + .../pryjs/docs/_sass/layouts/_index.scss | 45 + .../pryjs/docs/_sass/layouts/_posts.scss | 81 + node_modules/pryjs/docs/css/main.scss | 18 + node_modules/pryjs/docs/favicon.ico | Bin 0 -> 1150 bytes node_modules/pryjs/docs/img/pryjs.jpg | Bin 0 -> 42083 bytes .../pryjs/docs/img/sample_feature_img.png | Bin 0 -> 30756 bytes .../pryjs/docs/img/sample_feature_img_2.png | Bin 0 -> 29963 bytes .../pryjs/docs/img/sample_feature_img_3.png | Bin 0 -> 96785 bytes node_modules/pryjs/docs/index.md | 61 + node_modules/pryjs/docs/js/katex_init.js | 22 + node_modules/pryjs/examples/fizzbuzz.coffee | 18 + node_modules/pryjs/examples/fizzbuzz.js | 21 + node_modules/pryjs/examples/package.json | 10 + node_modules/pryjs/features/continue.feature | 16 + node_modules/pryjs/features/help.feature | 23 + node_modules/pryjs/features/play.feature | 18 + .../step_definitions/myStepDefinitions.coffee | 42 + .../pryjs/features/support/after_hooks.coffee | 4 + .../pryjs/features/support/world.coffee | 56 + .../pryjs/features/underscore.feature | 10 + node_modules/pryjs/features/version.feature | 9 + node_modules/pryjs/features/whereami.feature | 19 + node_modules/pryjs/features/wtf.feature | 15 + node_modules/pryjs/features/xecute.feature | 62 + node_modules/pryjs/lib/.gitkeep | 0 node_modules/pryjs/package.json | 76 + node_modules/pryjs/readme.md | 50 + node_modules/pryjs/src/pry.coffee | 19 + node_modules/pryjs/src/pry/app.coffee | 41 + node_modules/pryjs/src/pry/command.coffee | 61 + .../pryjs/src/pry/commands/continue.coffee | 12 + .../pryjs/src/pry/commands/help.coffee | 34 + .../pryjs/src/pry/commands/index.coffee | 7 + .../pryjs/src/pry/commands/kill.coffee | 14 + .../pryjs/src/pry/commands/play.coffee | 20 + .../pryjs/src/pry/commands/version.coffee | 13 + .../pryjs/src/pry/commands/whereami.coffee | 25 + .../pryjs/src/pry/commands/wtf.coffee | 16 + .../pryjs/src/pry/commands/xecute.coffee | 40 + node_modules/pryjs/src/pry/compiler.coffee | 31 + node_modules/pryjs/src/pry/file.coffee | 28 + .../pryjs/src/pry/output/local_output.coffee | 16 + node_modules/pryjs/src/pry/range.coffee | 18 + .../pryjs/src/pry/sync_highlight.coffee | 55 + node_modules/pryjs/src/pry/sync_prompt.coffee | 96 + node_modules/pryjs/tests/app_spec.coffee | 69 + node_modules/pryjs/tests/command_spec.coffee | 107 + .../pryjs/tests/commands/help_spec.coffee | 25 + .../pryjs/tests/commands/whereami_spec.coffee | 38 + node_modules/pryjs/tests/compiler_spec.coffee | 46 + node_modules/pryjs/tests/file_spec.coffee | 46 + node_modules/pryjs/tests/range_spec.coffee | 49 + .../pryjs/tests/sync_highlight_spec.coffee | 23 + node_modules/pygmentize-bundled/.jshintrc | 59 + node_modules/pygmentize-bundled/.npmignore | 8 + node_modules/pygmentize-bundled/LICENSE | 39 + node_modules/pygmentize-bundled/README.md | 96 + node_modules/pygmentize-bundled/index.js | 144 + node_modules/pygmentize-bundled/package.json | 65 + .../test-fixtures/active_model.html | 222 + .../test-fixtures/active_model.rb | 221 + node_modules/pygmentize-bundled/test.js | 104 + .../vendor/pygments/AUTHORS | 172 + .../vendor/pygments/CHANGES | 941 + .../vendor/pygments/LICENSE | 25 + .../vendor/pygments/MANIFEST.in | 6 + .../vendor/pygments/Makefile | 56 + .../pygmentize-bundled/vendor/pygments/TODO | 15 + .../vendor/pygments/build-2.7/pygmentize | 7 + .../pygments/build-2.7/pygments/__init__.py | 91 + .../pygments/build-2.7/pygments/__init__.pyc | Bin 0 -> 3741 bytes .../pygments/build-2.7/pygments/cmdline.py | 454 + .../pygments/build-2.7/pygments/cmdline.pyc | Bin 0 -> 11781 bytes .../pygments/build-2.7/pygments/console.py | 74 + .../pygments/build-2.7/pygments/console.pyc | Bin 0 -> 2725 bytes .../pygments/build-2.7/pygments/filter.py | 74 + .../pygments/build-2.7/pygments/filter.pyc | Bin 0 -> 4166 bytes .../build-2.7/pygments/filters/__init__.py | 358 + .../build-2.7/pygments/filters/__init__.pyc | Bin 0 -> 16912 bytes .../pygments/build-2.7/pygments/formatter.py | 95 + .../pygments/build-2.7/pygments/formatter.pyc | Bin 0 -> 4001 bytes .../build-2.7/pygments/formatters/__init__.py | 70 + .../pygments/formatters/__init__.pyc | Bin 0 -> 3181 bytes .../build-2.7/pygments/formatters/_mapping.py | 103 + .../pygments/formatters/_mapping.pyc | Bin 0 -> 6395 bytes .../build-2.7/pygments/formatters/bbcode.py | 109 + .../build-2.7/pygments/formatters/bbcode.pyc | Bin 0 -> 4042 bytes .../build-2.7/pygments/formatters/html.py | 839 + .../build-2.7/pygments/formatters/html.pyc | Bin 0 -> 30617 bytes .../build-2.7/pygments/formatters/img.py | 560 + .../build-2.7/pygments/formatters/img.pyc | Bin 0 -> 21306 bytes .../build-2.7/pygments/formatters/latex.py | 470 + .../build-2.7/pygments/formatters/latex.pyc | Bin 0 -> 15088 bytes .../build-2.7/pygments/formatters/other.py | 162 + .../build-2.7/pygments/formatters/other.pyc | Bin 0 -> 7475 bytes .../build-2.7/pygments/formatters/rtf.py | 150 + .../build-2.7/pygments/formatters/rtf.pyc | Bin 0 -> 5421 bytes .../build-2.7/pygments/formatters/svg.py | 154 + .../build-2.7/pygments/formatters/svg.pyc | Bin 0 -> 6647 bytes .../build-2.7/pygments/formatters/terminal.py | 152 + .../pygments/formatters/terminal.pyc | Bin 0 -> 6383 bytes .../pygments/formatters/terminal256.py | 222 + .../pygments/formatters/terminal256.pyc | Bin 0 -> 8687 bytes .../pygments/build-2.7/pygments/lexer.py | 785 + .../pygments/build-2.7/pygments/lexer.pyc | Bin 0 -> 30318 bytes .../build-2.7/pygments/lexers/__init__.py | 263 + .../build-2.7/pygments/lexers/__init__.pyc | Bin 0 -> 9986 bytes .../build-2.7/pygments/lexers/_asybuiltins.py | 1645 ++ .../build-2.7/pygments/lexers/_clbuiltins.py | 232 + .../pygments/lexers/_cocoabuiltins.py | 73 + .../pygments/lexers/_lassobuiltins.py | 5182 ++++++ .../build-2.7/pygments/lexers/_luabuiltins.py | 255 + .../build-2.7/pygments/lexers/_mapping.py | 400 + .../build-2.7/pygments/lexers/_mapping.pyc | Bin 0 -> 63042 bytes .../pygments/lexers/_openedgebuiltins.py | 562 + .../build-2.7/pygments/lexers/_phpbuiltins.py | 4759 +++++ .../pygments/lexers/_postgres_builtins.py | 233 + .../pygments/lexers/_robotframeworklexer.py | 558 + .../pygments/lexers/_scilab_builtins.py | 40 + .../pygments/lexers/_sourcemodbuiltins.py | 1077 ++ .../pygments/lexers/_stan_builtins.py | 454 + .../build-2.7/pygments/lexers/_vimbuiltins.py | 13 + .../build-2.7/pygments/lexers/agile.py | 2552 +++ .../build-2.7/pygments/lexers/agile.pyc | Bin 0 -> 91960 bytes .../pygments/build-2.7/pygments/lexers/asm.py | 435 + .../build-2.7/pygments/lexers/compiled.py | 5192 ++++++ .../build-2.7/pygments/lexers/compiled.pyc | Bin 0 -> 169049 bytes .../build-2.7/pygments/lexers/dalvik.py | 125 + .../build-2.7/pygments/lexers/dotnet.py | 683 + .../build-2.7/pygments/lexers/foxpro.py | 428 + .../build-2.7/pygments/lexers/functional.py | 3671 ++++ .../build-2.7/pygments/lexers/functional.pyc | Bin 0 -> 139168 bytes .../build-2.7/pygments/lexers/graph.py | 81 + .../pygments/build-2.7/pygments/lexers/hdl.py | 355 + .../build-2.7/pygments/lexers/inferno.py | 96 + .../pygments/build-2.7/pygments/lexers/jvm.py | 1527 ++ .../build-2.7/pygments/lexers/jvm.pyc | Bin 0 -> 49759 bytes .../build-2.7/pygments/lexers/math.py | 2286 +++ .../build-2.7/pygments/lexers/other.py | 4492 +++++ .../build-2.7/pygments/lexers/parsers.py | 778 + .../build-2.7/pygments/lexers/qbasic.py | 157 + .../pygments/build-2.7/pygments/lexers/rdf.py | 99 + .../build-2.7/pygments/lexers/shell.py | 427 + .../build-2.7/pygments/lexers/special.py | 99 + .../build-2.7/pygments/lexers/special.pyc | Bin 0 -> 4432 bytes .../pygments/build-2.7/pygments/lexers/sql.py | 592 + .../build-2.7/pygments/lexers/templates.py | 2060 +++ .../build-2.7/pygments/lexers/text.py | 2055 +++ .../pygments/build-2.7/pygments/lexers/web.py | 4510 +++++ .../build-2.7/pygments/lexers/web.pyc | Bin 0 -> 129273 bytes .../pygments/build-2.7/pygments/modeline.py | 40 + .../pygments/build-2.7/pygments/modeline.pyc | Bin 0 -> 1627 bytes .../pygments/build-2.7/pygments/plugin.py | 74 + .../pygments/build-2.7/pygments/plugin.pyc | Bin 0 -> 2850 bytes .../pygments/build-2.7/pygments/scanner.py | 104 + .../pygments/build-2.7/pygments/scanner.pyc | Bin 0 -> 5154 bytes .../pygments/build-2.7/pygments/sphinxext.py | 153 + .../pygments/build-2.7/pygments/style.py | 118 + .../pygments/build-2.7/pygments/style.pyc | Bin 0 -> 4917 bytes .../build-2.7/pygments/styles/__init__.py | 74 + .../build-2.7/pygments/styles/__init__.pyc | Bin 0 -> 2958 bytes .../build-2.7/pygments/styles/autumn.py | 65 + .../build-2.7/pygments/styles/borland.py | 51 + .../pygments/build-2.7/pygments/styles/bw.py | 49 + .../build-2.7/pygments/styles/colorful.py | 81 + .../build-2.7/pygments/styles/default.py | 73 + .../build-2.7/pygments/styles/default.pyc | Bin 0 -> 2544 bytes .../build-2.7/pygments/styles/emacs.py | 72 + .../build-2.7/pygments/styles/friendly.py | 72 + .../build-2.7/pygments/styles/fruity.py | 42 + .../build-2.7/pygments/styles/igor.py | 29 + .../build-2.7/pygments/styles/manni.py | 75 + .../build-2.7/pygments/styles/monokai.py | 106 + .../build-2.7/pygments/styles/murphy.py | 80 + .../build-2.7/pygments/styles/native.py | 65 + .../build-2.7/pygments/styles/paraiso_dark.py | 125 + .../pygments/styles/paraiso_light.py | 125 + .../build-2.7/pygments/styles/pastie.py | 75 + .../build-2.7/pygments/styles/perldoc.py | 69 + .../pygments/build-2.7/pygments/styles/rrt.py | 33 + .../build-2.7/pygments/styles/tango.py | 141 + .../build-2.7/pygments/styles/trac.py | 63 + .../pygments/build-2.7/pygments/styles/vim.py | 63 + .../pygments/build-2.7/pygments/styles/vs.py | 38 + .../build-2.7/pygments/styles/xcode.py | 51 + .../pygments/build-2.7/pygments/token.py | 198 + .../pygments/build-2.7/pygments/token.pyc | Bin 0 -> 6054 bytes .../pygments/build-2.7/pygments/unistring.py | 141 + .../pygments/build-2.7/pygments/unistring.pyc | Bin 0 -> 209039 bytes .../pygments/build-2.7/pygments/util.py | 291 + .../pygments/build-2.7/pygments/util.pyc | Bin 0 -> 11206 bytes .../vendor/pygments/build-3.3/pygmentize | 7 + .../pygments/build-3.3/pygments/__init__.py | 91 + .../pygments/build-3.3/pygments/cmdline.py | 454 + .../pygments/build-3.3/pygments/console.py | 74 + .../pygments/build-3.3/pygments/filter.py | 74 + .../build-3.3/pygments/filters/__init__.py | 358 + .../pygments/build-3.3/pygments/formatter.py | 95 + .../build-3.3/pygments/formatters/__init__.py | 70 + .../build-3.3/pygments/formatters/_mapping.py | 103 + .../build-3.3/pygments/formatters/bbcode.py | 109 + .../build-3.3/pygments/formatters/html.py | 839 + .../build-3.3/pygments/formatters/img.py | 560 + .../build-3.3/pygments/formatters/latex.py | 470 + .../build-3.3/pygments/formatters/other.py | 162 + .../build-3.3/pygments/formatters/rtf.py | 150 + .../build-3.3/pygments/formatters/svg.py | 154 + .../build-3.3/pygments/formatters/terminal.py | 152 + .../pygments/formatters/terminal256.py | 222 + .../pygments/build-3.3/pygments/lexer.py | 785 + .../build-3.3/pygments/lexers/__init__.py | 263 + .../build-3.3/pygments/lexers/_asybuiltins.py | 1645 ++ .../build-3.3/pygments/lexers/_clbuiltins.py | 232 + .../pygments/lexers/_cocoabuiltins.py | 73 + .../pygments/lexers/_lassobuiltins.py | 5182 ++++++ .../build-3.3/pygments/lexers/_luabuiltins.py | 255 + .../build-3.3/pygments/lexers/_mapping.py | 400 + .../pygments/lexers/_openedgebuiltins.py | 562 + .../build-3.3/pygments/lexers/_phpbuiltins.py | 4759 +++++ .../pygments/lexers/_postgres_builtins.py | 233 + .../pygments/lexers/_robotframeworklexer.py | 558 + .../pygments/lexers/_scilab_builtins.py | 40 + .../pygments/lexers/_sourcemodbuiltins.py | 1077 ++ .../pygments/lexers/_stan_builtins.py | 454 + .../build-3.3/pygments/lexers/_vimbuiltins.py | 13 + .../build-3.3/pygments/lexers/agile.py | 2552 +++ .../pygments/build-3.3/pygments/lexers/asm.py | 435 + .../build-3.3/pygments/lexers/compiled.py | 5192 ++++++ .../build-3.3/pygments/lexers/dalvik.py | 125 + .../build-3.3/pygments/lexers/dotnet.py | 683 + .../build-3.3/pygments/lexers/foxpro.py | 428 + .../build-3.3/pygments/lexers/functional.py | 3671 ++++ .../build-3.3/pygments/lexers/graph.py | 81 + .../pygments/build-3.3/pygments/lexers/hdl.py | 355 + .../build-3.3/pygments/lexers/inferno.py | 96 + .../pygments/build-3.3/pygments/lexers/jvm.py | 1527 ++ .../build-3.3/pygments/lexers/math.py | 2286 +++ .../build-3.3/pygments/lexers/other.py | 4492 +++++ .../build-3.3/pygments/lexers/parsers.py | 778 + .../build-3.3/pygments/lexers/qbasic.py | 157 + .../pygments/build-3.3/pygments/lexers/rdf.py | 99 + .../build-3.3/pygments/lexers/shell.py | 427 + .../build-3.3/pygments/lexers/special.py | 99 + .../pygments/build-3.3/pygments/lexers/sql.py | 592 + .../build-3.3/pygments/lexers/templates.py | 2060 +++ .../build-3.3/pygments/lexers/text.py | 2055 +++ .../pygments/build-3.3/pygments/lexers/web.py | 4510 +++++ .../pygments/build-3.3/pygments/modeline.py | 40 + .../pygments/build-3.3/pygments/plugin.py | 74 + .../pygments/build-3.3/pygments/scanner.py | 104 + .../pygments/build-3.3/pygments/sphinxext.py | 153 + .../pygments/build-3.3/pygments/style.py | 118 + .../build-3.3/pygments/styles/__init__.py | 74 + .../build-3.3/pygments/styles/autumn.py | 65 + .../build-3.3/pygments/styles/borland.py | 51 + .../pygments/build-3.3/pygments/styles/bw.py | 49 + .../build-3.3/pygments/styles/colorful.py | 81 + .../build-3.3/pygments/styles/default.py | 73 + .../build-3.3/pygments/styles/emacs.py | 72 + .../build-3.3/pygments/styles/friendly.py | 72 + .../build-3.3/pygments/styles/fruity.py | 42 + .../build-3.3/pygments/styles/igor.py | 29 + .../build-3.3/pygments/styles/manni.py | 75 + .../build-3.3/pygments/styles/monokai.py | 106 + .../build-3.3/pygments/styles/murphy.py | 80 + .../build-3.3/pygments/styles/native.py | 65 + .../build-3.3/pygments/styles/paraiso_dark.py | 125 + .../pygments/styles/paraiso_light.py | 125 + .../build-3.3/pygments/styles/pastie.py | 75 + .../build-3.3/pygments/styles/perldoc.py | 69 + .../pygments/build-3.3/pygments/styles/rrt.py | 33 + .../build-3.3/pygments/styles/tango.py | 141 + .../build-3.3/pygments/styles/trac.py | 63 + .../pygments/build-3.3/pygments/styles/vim.py | 63 + .../pygments/build-3.3/pygments/styles/vs.py | 38 + .../build-3.3/pygments/styles/xcode.py | 51 + .../pygments/build-3.3/pygments/token.py | 198 + .../pygments/build-3.3/pygments/unistring.py | 141 + .../pygments/build-3.3/pygments/util.py | 291 + .../vendor/pygments/doc/Makefile | 153 + .../vendor/pygments/doc/_static/favicon.ico | Bin 0 -> 16958 bytes .../vendor/pygments/doc/_static/logo_new.png | Bin 0 -> 40944 bytes .../vendor/pygments/doc/_static/logo_only.png | Bin 0 -> 16424 bytes .../pygments/doc/_templates/docssidebar.html | 3 + .../pygments/doc/_templates/indexsidebar.html | 25 + .../doc/_themes/pygments14/layout.html | 98 + .../doc/_themes/pygments14/static/bodybg.png | Bin 0 -> 51903 bytes .../doc/_themes/pygments14/static/docbg.png | Bin 0 -> 61296 bytes .../_themes/pygments14/static/listitem.png | Bin 0 -> 207 bytes .../doc/_themes/pygments14/static/logo.png | Bin 0 -> 26933 bytes .../doc/_themes/pygments14/static/pocoo.png | Bin 0 -> 2154 bytes .../pygments14/static/pygments14.css_t | 401 + .../doc/_themes/pygments14/theme.conf | 15 + .../vendor/pygments/doc/conf.py | 249 + .../vendor/pygments/doc/docs/api.rst | 316 + .../vendor/pygments/doc/docs/authors.rst | 4 + .../vendor/pygments/doc/docs/changelog.rst | 1 + .../vendor/pygments/doc/docs/cmdline.rst | 145 + .../pygments/doc/docs/filterdevelopment.rst | 70 + .../vendor/pygments/doc/docs/filters.rst | 41 + .../doc/docs/formatterdevelopment.rst | 169 + .../vendor/pygments/doc/docs/formatters.rst | 48 + .../vendor/pygments/doc/docs/index.rst | 66 + .../vendor/pygments/doc/docs/integrate.rst | 44 + .../vendor/pygments/doc/docs/java.rst | 70 + .../pygments/doc/docs/lexerdevelopment.rst | 602 + .../vendor/pygments/doc/docs/lexers.rst | 69 + .../vendor/pygments/doc/docs/moinmoin.rst | 39 + .../vendor/pygments/doc/docs/plugins.rst | 93 + .../vendor/pygments/doc/docs/quickstart.rst | 205 + .../vendor/pygments/doc/docs/rstdirective.rst | 22 + .../vendor/pygments/doc/docs/styles.rst | 143 + .../vendor/pygments/doc/docs/tokens.rst | 352 + .../vendor/pygments/doc/docs/unicode.rst | 50 + .../vendor/pygments/doc/download.rst | 41 + .../vendor/pygments/doc/faq.rst | 143 + .../vendor/pygments/doc/index.rst | 53 + .../vendor/pygments/doc/languages.rst | 151 + .../vendor/pygments/doc/make.bat | 190 + .../vendor/pygments/doc/pygmentize.1 | 94 + .../vendor/pygments/external/autopygmentize | 81 + .../external/lasso-builtins-generator-9.lasso | 144 + .../pygments/external/markdown-processor.py | 67 + .../vendor/pygments/external/moin-parser.py | 112 + .../pygments/external/pygments.bashcomp | 38 + .../vendor/pygments/external/rst-directive.py | 82 + .../vendor/pygments/ez_setup.py | 382 + .../vendor/pygments/pygmentize | 7 + .../vendor/pygments/pygments/__init__.py | 91 + .../vendor/pygments/pygments/cmdline.py | 454 + .../vendor/pygments/pygments/console.py | 74 + .../vendor/pygments/pygments/filter.py | 74 + .../pygments/pygments/filters/__init__.py | 358 + .../vendor/pygments/pygments/formatter.py | 95 + .../pygments/pygments/formatters/__init__.py | 70 + .../pygments/pygments/formatters/_mapping.py | 103 + .../pygments/pygments/formatters/bbcode.py | 109 + .../pygments/pygments/formatters/html.py | 839 + .../pygments/pygments/formatters/img.py | 560 + .../pygments/pygments/formatters/latex.py | 470 + .../pygments/pygments/formatters/other.py | 162 + .../pygments/pygments/formatters/rtf.py | 150 + .../pygments/pygments/formatters/svg.py | 154 + .../pygments/pygments/formatters/terminal.py | 152 + .../pygments/formatters/terminal256.py | 222 + .../vendor/pygments/pygments/lexer.py | 785 + .../pygments/pygments/lexers/__init__.py | 263 + .../pygments/pygments/lexers/_asybuiltins.py | 1645 ++ .../pygments/pygments/lexers/_clbuiltins.py | 232 + .../pygments/lexers/_cocoabuiltins.py | 73 + .../pygments/lexers/_lassobuiltins.py | 5182 ++++++ .../pygments/pygments/lexers/_luabuiltins.py | 255 + .../pygments/pygments/lexers/_mapping.py | 400 + .../pygments/lexers/_openedgebuiltins.py | 562 + .../pygments/pygments/lexers/_phpbuiltins.py | 4759 +++++ .../pygments/lexers/_postgres_builtins.py | 233 + .../pygments/lexers/_robotframeworklexer.py | 558 + .../pygments/lexers/_scilab_builtins.py | 40 + .../pygments/lexers/_sourcemodbuiltins.py | 1077 ++ .../pygments/lexers/_stan_builtins.py | 454 + .../pygments/pygments/lexers/_vimbuiltins.py | 13 + .../vendor/pygments/pygments/lexers/agile.py | 2552 +++ .../vendor/pygments/pygments/lexers/asm.py | 435 + .../pygments/pygments/lexers/compiled.py | 5192 ++++++ .../vendor/pygments/pygments/lexers/dalvik.py | 125 + .../vendor/pygments/pygments/lexers/dotnet.py | 683 + .../vendor/pygments/pygments/lexers/foxpro.py | 428 + .../pygments/pygments/lexers/functional.py | 3671 ++++ .../vendor/pygments/pygments/lexers/graph.py | 81 + .../vendor/pygments/pygments/lexers/hdl.py | 355 + .../pygments/pygments/lexers/inferno.py | 96 + .../vendor/pygments/pygments/lexers/jvm.py | 1527 ++ .../vendor/pygments/pygments/lexers/math.py | 2286 +++ .../vendor/pygments/pygments/lexers/other.py | 4492 +++++ .../pygments/pygments/lexers/parsers.py | 778 + .../vendor/pygments/pygments/lexers/qbasic.py | 157 + .../vendor/pygments/pygments/lexers/rdf.py | 99 + .../vendor/pygments/pygments/lexers/shell.py | 427 + .../pygments/pygments/lexers/special.py | 99 + .../vendor/pygments/pygments/lexers/sql.py | 592 + .../pygments/pygments/lexers/templates.py | 2060 +++ .../vendor/pygments/pygments/lexers/text.py | 2055 +++ .../vendor/pygments/pygments/lexers/web.py | 4510 +++++ .../vendor/pygments/pygments/modeline.py | 40 + .../vendor/pygments/pygments/plugin.py | 74 + .../vendor/pygments/pygments/scanner.py | 104 + .../vendor/pygments/pygments/sphinxext.py | 153 + .../vendor/pygments/pygments/style.py | 118 + .../pygments/pygments/styles/__init__.py | 74 + .../vendor/pygments/pygments/styles/autumn.py | 65 + .../pygments/pygments/styles/borland.py | 51 + .../vendor/pygments/pygments/styles/bw.py | 49 + .../pygments/pygments/styles/colorful.py | 81 + .../pygments/pygments/styles/default.py | 73 + .../vendor/pygments/pygments/styles/emacs.py | 72 + .../pygments/pygments/styles/friendly.py | 72 + .../vendor/pygments/pygments/styles/fruity.py | 42 + .../vendor/pygments/pygments/styles/igor.py | 29 + .../vendor/pygments/pygments/styles/manni.py | 75 + .../pygments/pygments/styles/monokai.py | 106 + .../vendor/pygments/pygments/styles/murphy.py | 80 + .../vendor/pygments/pygments/styles/native.py | 65 + .../pygments/pygments/styles/paraiso_dark.py | 125 + .../pygments/pygments/styles/paraiso_light.py | 125 + .../vendor/pygments/pygments/styles/pastie.py | 75 + .../pygments/pygments/styles/perldoc.py | 69 + .../vendor/pygments/pygments/styles/rrt.py | 33 + .../vendor/pygments/pygments/styles/tango.py | 141 + .../vendor/pygments/pygments/styles/trac.py | 63 + .../vendor/pygments/pygments/styles/vim.py | 63 + .../vendor/pygments/pygments/styles/vs.py | 38 + .../vendor/pygments/pygments/styles/xcode.py | 51 + .../vendor/pygments/pygments/token.py | 198 + .../vendor/pygments/pygments/unistring.py | 141 + .../vendor/pygments/pygments/util.py | 291 + .../vendor/pygments/scripts/check_sources.py | 226 + .../scripts/detect_missing_analyse_text.py | 33 + .../vendor/pygments/scripts/epydoc.css | 280 + .../vendor/pygments/scripts/find_codetags.py | 213 + .../vendor/pygments/scripts/find_error.py | 173 + .../vendor/pygments/scripts/get_vimkw.py | 43 + .../vendor/pygments/scripts/pylintrc | 301 + .../vendor/pygments/scripts/vim2pygments.py | 935 + .../vendor/pygments/setup.cfg | 7 + .../vendor/pygments/setup.py | 90 + node_modules/readable-stream/.npmignore | 5 + node_modules/readable-stream/LICENSE | 18 + node_modules/readable-stream/README.md | 15 + node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 89 + .../lib/_stream_passthrough.js | 46 + .../readable-stream/lib/_stream_readable.js | 982 + .../readable-stream/lib/_stream_transform.js | 210 + .../readable-stream/lib/_stream_writable.js | 386 + node_modules/readable-stream/package.json | 65 + node_modules/readable-stream/passthrough.js | 1 + node_modules/readable-stream/readable.js | 11 + node_modules/readable-stream/transform.js | 1 + node_modules/readable-stream/writable.js | 1 + node_modules/string_decoder/.npmignore | 2 + node_modules/string_decoder/LICENSE | 20 + node_modules/string_decoder/README.md | 7 + node_modules/string_decoder/index.js | 221 + node_modules/string_decoder/package.json | 54 + node_modules/strip-ansi/cli.js | 39 + node_modules/strip-ansi/index.js | 6 + node_modules/strip-ansi/package.json | 88 + node_modules/strip-ansi/readme.md | 43 + node_modules/supports-color/browser.js | 2 + node_modules/supports-color/index.js | 115 + node_modules/supports-color/license | 9 + node_modules/supports-color/package.json | 85 + node_modules/supports-color/readme.md | 66 + node_modules/through2/.jshintrc | 59 + node_modules/through2/.npmignore | 1 + node_modules/through2/.travis.yml | 12 + node_modules/through2/LICENSE | 39 + node_modules/through2/README.md | 107 + .../node_modules/readable-stream/.npmignore | 5 + .../node_modules/readable-stream/LICENSE | 18 + .../node_modules/readable-stream/README.md | 15 + .../node_modules/readable-stream/duplex.js | 1 + .../node_modules/readable-stream/float.patch | 923 + .../readable-stream/lib/_stream_duplex.js | 89 + .../lib/_stream_passthrough.js | 46 + .../readable-stream/lib/_stream_readable.js | 951 + .../readable-stream/lib/_stream_transform.js | 209 + .../readable-stream/lib/_stream_writable.js | 477 + .../node_modules/readable-stream/package.json | 65 + .../readable-stream/passthrough.js | 1 + .../node_modules/readable-stream/readable.js | 10 + .../node_modules/readable-stream/transform.js | 1 + .../node_modules/readable-stream/writable.js | 1 + node_modules/through2/package.json | 68 + node_modules/through2/test.js | 314 + node_modules/through2/through2.js | 42 + node_modules/type-detect/LICENSE | 19 + node_modules/type-detect/README.md | 228 + node_modules/type-detect/index.js | 378 + node_modules/type-detect/package.json | 169 + node_modules/type-detect/type-detect.js | 388 + node_modules/underscore/LICENSE | 23 + node_modules/underscore/README.md | 22 + node_modules/underscore/package.json | 73 + node_modules/underscore/underscore-min.js | 6 + node_modules/underscore/underscore-min.map | 1 + node_modules/underscore/underscore.js | 1548 ++ node_modules/wrappy/LICENSE | 15 + node_modules/wrappy/README.md | 36 + node_modules/wrappy/package.json | 59 + node_modules/wrappy/wrappy.js | 33 + node_modules/xtend/.npmignore | 1 + node_modules/xtend/LICENCE | 19 + node_modules/xtend/Makefile | 4 + node_modules/xtend/README.md | 27 + node_modules/xtend/has-keys.js | 7 + node_modules/xtend/index.js | 25 + node_modules/xtend/mutable.js | 25 + node_modules/xtend/package.json | 93 + node_modules/xtend/test.js | 63 + package-lock.json | 386 + package.json | 29 + rectangles.js | 36 + test/rectangles-test.js | 39 + 1024 files changed, 293788 insertions(+) create mode 120000 node_modules/.bin/_mocha create mode 120000 node_modules/.bin/cake create mode 120000 node_modules/.bin/coffee create mode 120000 node_modules/.bin/has-ansi create mode 120000 node_modules/.bin/he create mode 120000 node_modules/.bin/mkdirp create mode 120000 node_modules/.bin/mocha create mode 120000 node_modules/.bin/pryjs create mode 120000 node_modules/.bin/strip-ansi create mode 100644 node_modules/ansi-regex/index.js create mode 100644 node_modules/ansi-regex/package.json create mode 100644 node_modules/ansi-regex/readme.md create mode 100644 node_modules/ansi-styles/index.js create mode 100644 node_modules/ansi-styles/package.json create mode 100644 node_modules/ansi-styles/readme.md create mode 100644 node_modules/assertion-error/History.md create mode 100644 node_modules/assertion-error/README.md create mode 100644 node_modules/assertion-error/index.d.ts create mode 100644 node_modules/assertion-error/index.js create mode 100644 node_modules/assertion-error/package.json create mode 100644 node_modules/balanced-match/.npmignore create mode 100644 node_modules/balanced-match/LICENSE.md create mode 100644 node_modules/balanced-match/README.md create mode 100644 node_modules/balanced-match/index.js create mode 100644 node_modules/balanced-match/package.json create mode 100644 node_modules/bindings/README.md create mode 100644 node_modules/bindings/bindings.js create mode 100644 node_modules/bindings/package.json create mode 100644 node_modules/bl/.jshintrc create mode 100644 node_modules/bl/.npmignore create mode 100644 node_modules/bl/.travis.yml create mode 100644 node_modules/bl/LICENSE create mode 100644 node_modules/bl/README.md create mode 100644 node_modules/bl/bl.js create mode 100644 node_modules/bl/package.json create mode 100644 node_modules/bl/test.js create mode 100644 node_modules/brace-expansion/LICENSE create mode 100644 node_modules/brace-expansion/README.md create mode 100644 node_modules/brace-expansion/index.js create mode 100644 node_modules/brace-expansion/package.json create mode 100644 node_modules/browser-stdout/LICENSE create mode 100644 node_modules/browser-stdout/README.md create mode 100644 node_modules/browser-stdout/index.js create mode 100644 node_modules/browser-stdout/package.json create mode 100644 node_modules/chai/.npmignore create mode 100644 node_modules/chai/CODEOWNERS create mode 100644 node_modules/chai/CODE_OF_CONDUCT.md create mode 100644 node_modules/chai/CONTRIBUTING.md create mode 100644 node_modules/chai/History.md create mode 100644 node_modules/chai/LICENSE create mode 100644 node_modules/chai/README.md create mode 100644 node_modules/chai/ReleaseNotes.md create mode 100644 node_modules/chai/chai.js create mode 100644 node_modules/chai/index.js create mode 100644 node_modules/chai/karma.conf.js create mode 100644 node_modules/chai/karma.sauce.js create mode 100644 node_modules/chai/lib/chai.js create mode 100644 node_modules/chai/lib/chai/assertion.js create mode 100644 node_modules/chai/lib/chai/config.js create mode 100644 node_modules/chai/lib/chai/core/assertions.js create mode 100644 node_modules/chai/lib/chai/interface/assert.js create mode 100644 node_modules/chai/lib/chai/interface/expect.js create mode 100644 node_modules/chai/lib/chai/interface/should.js create mode 100644 node_modules/chai/lib/chai/utils/addChainableMethod.js create mode 100644 node_modules/chai/lib/chai/utils/addLengthGuard.js create mode 100644 node_modules/chai/lib/chai/utils/addMethod.js create mode 100644 node_modules/chai/lib/chai/utils/addProperty.js create mode 100644 node_modules/chai/lib/chai/utils/compareByInspect.js create mode 100644 node_modules/chai/lib/chai/utils/expectTypes.js create mode 100644 node_modules/chai/lib/chai/utils/flag.js create mode 100644 node_modules/chai/lib/chai/utils/getActual.js create mode 100644 node_modules/chai/lib/chai/utils/getEnumerableProperties.js create mode 100644 node_modules/chai/lib/chai/utils/getMessage.js create mode 100644 node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js create mode 100644 node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js create mode 100644 node_modules/chai/lib/chai/utils/getProperties.js create mode 100644 node_modules/chai/lib/chai/utils/index.js create mode 100644 node_modules/chai/lib/chai/utils/inspect.js create mode 100644 node_modules/chai/lib/chai/utils/isNaN.js create mode 100644 node_modules/chai/lib/chai/utils/isProxyEnabled.js create mode 100644 node_modules/chai/lib/chai/utils/objDisplay.js create mode 100644 node_modules/chai/lib/chai/utils/overwriteChainableMethod.js create mode 100644 node_modules/chai/lib/chai/utils/overwriteMethod.js create mode 100644 node_modules/chai/lib/chai/utils/overwriteProperty.js create mode 100644 node_modules/chai/lib/chai/utils/proxify.js create mode 100644 node_modules/chai/lib/chai/utils/test.js create mode 100644 node_modules/chai/lib/chai/utils/transferFlags.js create mode 100644 node_modules/chai/package.json create mode 100644 node_modules/chai/register-assert.js create mode 100644 node_modules/chai/register-expect.js create mode 100644 node_modules/chai/register-should.js create mode 100644 node_modules/chai/sauce.browsers.js create mode 100644 node_modules/chalk/index.js create mode 120000 node_modules/chalk/node_modules/.bin/supports-color create mode 100755 node_modules/chalk/node_modules/supports-color/cli.js create mode 100644 node_modules/chalk/node_modules/supports-color/index.js create mode 100644 node_modules/chalk/node_modules/supports-color/package.json create mode 100644 node_modules/chalk/node_modules/supports-color/readme.md create mode 100644 node_modules/chalk/package.json create mode 100644 node_modules/chalk/readme.md create mode 100644 node_modules/check-error/LICENSE create mode 100644 node_modules/check-error/README.md create mode 100644 node_modules/check-error/check-error.js create mode 100644 node_modules/check-error/index.js create mode 100644 node_modules/check-error/package.json create mode 100644 node_modules/coffee-script/LICENSE create mode 100644 node_modules/coffee-script/README.md create mode 100755 node_modules/coffee-script/bin/cake create mode 100755 node_modules/coffee-script/bin/coffee create mode 100644 node_modules/coffee-script/lib/coffee-script/browser.js create mode 100644 node_modules/coffee-script/lib/coffee-script/cake.js create mode 100644 node_modules/coffee-script/lib/coffee-script/coffee-script.js create mode 100644 node_modules/coffee-script/lib/coffee-script/command.js create mode 100644 node_modules/coffee-script/lib/coffee-script/grammar.js create mode 100644 node_modules/coffee-script/lib/coffee-script/helpers.js create mode 100644 node_modules/coffee-script/lib/coffee-script/index.js create mode 100644 node_modules/coffee-script/lib/coffee-script/lexer.js create mode 100644 node_modules/coffee-script/lib/coffee-script/nodes.js create mode 100644 node_modules/coffee-script/lib/coffee-script/optparse.js create mode 100755 node_modules/coffee-script/lib/coffee-script/parser.js create mode 100644 node_modules/coffee-script/lib/coffee-script/register.js create mode 100644 node_modules/coffee-script/lib/coffee-script/repl.js create mode 100644 node_modules/coffee-script/lib/coffee-script/rewriter.js create mode 100644 node_modules/coffee-script/lib/coffee-script/scope.js create mode 100644 node_modules/coffee-script/lib/coffee-script/sourcemap.js create mode 100644 node_modules/coffee-script/package.json create mode 100644 node_modules/coffee-script/register.js create mode 100644 node_modules/coffee-script/repl.js create mode 100644 node_modules/commander/History.md create mode 100644 node_modules/commander/LICENSE create mode 100644 node_modules/commander/Readme.md create mode 100644 node_modules/commander/index.js create mode 100644 node_modules/commander/package.json create mode 100644 node_modules/concat-map/.travis.yml create mode 100644 node_modules/concat-map/LICENSE create mode 100644 node_modules/concat-map/README.markdown create mode 100644 node_modules/concat-map/example/map.js create mode 100644 node_modules/concat-map/index.js create mode 100644 node_modules/concat-map/package.json create mode 100644 node_modules/concat-map/test/map.js create mode 100644 node_modules/core-util-is/LICENSE create mode 100644 node_modules/core-util-is/README.md create mode 100644 node_modules/core-util-is/float.patch create mode 100644 node_modules/core-util-is/lib/util.js create mode 100644 node_modules/core-util-is/package.json create mode 100644 node_modules/core-util-is/test.js create mode 100644 node_modules/deasync/README.md create mode 100644 node_modules/deasync/bin/darwin-x64-node-0.10/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-0.11/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-0.12/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-4/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-5/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-6/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-7/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-8/deasync.node create mode 100644 node_modules/deasync/bin/darwin-x64-node-9/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-0.10/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-0.11/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-0.12/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-4/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-5/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-6/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-7/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-8/deasync.node create mode 100644 node_modules/deasync/bin/linux-ia32-node-9/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-0.10/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-0.11/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-0.12/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-4/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-5/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-6/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-7/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-8/deasync.node create mode 100644 node_modules/deasync/bin/linux-x64-node-9/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-0.10/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-0.11/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-0.12/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-4/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-5/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-6/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-7/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-8/deasync.node create mode 100644 node_modules/deasync/bin/win32-ia32-node-9/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-0.10/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-0.11/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-0.12/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-4/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-5/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-6/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-7/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-8/deasync.node create mode 100644 node_modules/deasync/bin/win32-x64-node-9/deasync.node create mode 100644 node_modules/deasync/binding.gyp create mode 100644 node_modules/deasync/build.js create mode 100644 node_modules/deasync/index.js create mode 100644 node_modules/deasync/package.json create mode 100644 node_modules/deasync/quick-test.js create mode 100644 node_modules/deasync/src/deasync.cc create mode 100644 node_modules/deasync/test.js create mode 100644 node_modules/debug/.coveralls.yml create mode 100644 node_modules/debug/.eslintrc create mode 100644 node_modules/debug/.npmignore create mode 100644 node_modules/debug/.travis.yml create mode 100644 node_modules/debug/CHANGELOG.md create mode 100644 node_modules/debug/LICENSE create mode 100644 node_modules/debug/Makefile create mode 100644 node_modules/debug/README.md create mode 100644 node_modules/debug/karma.conf.js create mode 100644 node_modules/debug/node.js create mode 100644 node_modules/debug/package.json create mode 100644 node_modules/debug/src/browser.js create mode 100644 node_modules/debug/src/debug.js create mode 100644 node_modules/debug/src/index.js create mode 100644 node_modules/debug/src/node.js create mode 100644 node_modules/deep-eql/LICENSE create mode 100644 node_modules/deep-eql/README.md create mode 100644 node_modules/deep-eql/deep-eql.js create mode 100644 node_modules/deep-eql/index.js create mode 100644 node_modules/deep-eql/package.json create mode 100644 node_modules/diff/CONTRIBUTING.md create mode 100644 node_modules/diff/LICENSE create mode 100644 node_modules/diff/README.md create mode 100644 node_modules/diff/dist/diff.js create mode 100644 node_modules/diff/dist/diff.min.js create mode 100644 node_modules/diff/lib/convert/dmp.js create mode 100644 node_modules/diff/lib/convert/xml.js create mode 100644 node_modules/diff/lib/diff/array.js create mode 100644 node_modules/diff/lib/diff/base.js create mode 100644 node_modules/diff/lib/diff/character.js create mode 100644 node_modules/diff/lib/diff/css.js create mode 100644 node_modules/diff/lib/diff/json.js create mode 100644 node_modules/diff/lib/diff/line.js create mode 100644 node_modules/diff/lib/diff/sentence.js create mode 100644 node_modules/diff/lib/diff/word.js create mode 100644 node_modules/diff/lib/index.js create mode 100644 node_modules/diff/lib/patch/apply.js create mode 100644 node_modules/diff/lib/patch/create.js create mode 100644 node_modules/diff/lib/patch/merge.js create mode 100644 node_modules/diff/lib/patch/parse.js create mode 100644 node_modules/diff/lib/util/array.js create mode 100644 node_modules/diff/lib/util/distance-iterator.js create mode 100644 node_modules/diff/lib/util/params.js create mode 100644 node_modules/diff/package.json create mode 100644 node_modules/diff/release-notes.md create mode 100644 node_modules/diff/runtime.js create mode 100644 node_modules/diff/yarn.lock create mode 100644 node_modules/escape-string-regexp/index.js create mode 100644 node_modules/escape-string-regexp/license create mode 100644 node_modules/escape-string-regexp/package.json create mode 100644 node_modules/escape-string-regexp/readme.md create mode 100644 node_modules/fs.realpath/LICENSE create mode 100644 node_modules/fs.realpath/README.md create mode 100644 node_modules/fs.realpath/index.js create mode 100644 node_modules/fs.realpath/old.js create mode 100644 node_modules/fs.realpath/package.json create mode 100644 node_modules/get-func-name/LICENSE create mode 100644 node_modules/get-func-name/README.md create mode 100644 node_modules/get-func-name/get-func-name.js create mode 100644 node_modules/get-func-name/index.js create mode 100644 node_modules/get-func-name/package.json create mode 100644 node_modules/glob/LICENSE create mode 100644 node_modules/glob/README.md create mode 100644 node_modules/glob/changelog.md create mode 100644 node_modules/glob/common.js create mode 100644 node_modules/glob/glob.js create mode 100644 node_modules/glob/package.json create mode 100644 node_modules/glob/sync.js create mode 100644 node_modules/growl/.eslintrc.json create mode 100644 node_modules/growl/.tags create mode 100644 node_modules/growl/.tags1 create mode 100644 node_modules/growl/.travis.yml create mode 100644 node_modules/growl/History.md create mode 100644 node_modules/growl/Readme.md create mode 100644 node_modules/growl/lib/growl.js create mode 100644 node_modules/growl/package.json create mode 100644 node_modules/growl/test.js create mode 100755 node_modules/has-ansi/cli.js create mode 100644 node_modules/has-ansi/index.js create mode 100644 node_modules/has-ansi/package.json create mode 100644 node_modules/has-ansi/readme.md create mode 100644 node_modules/has-flag/index.js create mode 100644 node_modules/has-flag/license create mode 100644 node_modules/has-flag/package.json create mode 100644 node_modules/has-flag/readme.md create mode 100644 node_modules/he/LICENSE-MIT.txt create mode 100644 node_modules/he/README.md create mode 100755 node_modules/he/bin/he create mode 100644 node_modules/he/he.js create mode 100644 node_modules/he/man/he.1 create mode 100644 node_modules/he/package.json create mode 100644 node_modules/inflight/LICENSE create mode 100644 node_modules/inflight/README.md create mode 100644 node_modules/inflight/inflight.js create mode 100644 node_modules/inflight/package.json create mode 100644 node_modules/inherits/LICENSE create mode 100644 node_modules/inherits/README.md create mode 100644 node_modules/inherits/inherits.js create mode 100644 node_modules/inherits/inherits_browser.js create mode 100644 node_modules/inherits/package.json create mode 100644 node_modules/isarray/README.md create mode 100644 node_modules/isarray/build/build.js create mode 100644 node_modules/isarray/component.json create mode 100644 node_modules/isarray/index.js create mode 100644 node_modules/isarray/package.json create mode 100644 node_modules/minimatch/LICENSE create mode 100644 node_modules/minimatch/README.md create mode 100644 node_modules/minimatch/minimatch.js create mode 100644 node_modules/minimatch/package.json create mode 100644 node_modules/minimist/.travis.yml create mode 100644 node_modules/minimist/LICENSE create mode 100644 node_modules/minimist/example/parse.js create mode 100644 node_modules/minimist/index.js create mode 100644 node_modules/minimist/package.json create mode 100644 node_modules/minimist/readme.markdown create mode 100644 node_modules/minimist/test/dash.js create mode 100644 node_modules/minimist/test/default_bool.js create mode 100644 node_modules/minimist/test/dotted.js create mode 100644 node_modules/minimist/test/long.js create mode 100644 node_modules/minimist/test/parse.js create mode 100644 node_modules/minimist/test/parse_modified.js create mode 100644 node_modules/minimist/test/short.js create mode 100644 node_modules/minimist/test/whitespace.js create mode 100644 node_modules/mkdirp/.travis.yml create mode 100644 node_modules/mkdirp/LICENSE create mode 100755 node_modules/mkdirp/bin/cmd.js create mode 100644 node_modules/mkdirp/bin/usage.txt create mode 100644 node_modules/mkdirp/examples/pow.js create mode 100644 node_modules/mkdirp/index.js create mode 100644 node_modules/mkdirp/package.json create mode 100644 node_modules/mkdirp/readme.markdown create mode 100644 node_modules/mkdirp/test/chmod.js create mode 100644 node_modules/mkdirp/test/clobber.js create mode 100644 node_modules/mkdirp/test/mkdirp.js create mode 100644 node_modules/mkdirp/test/opts_fs.js create mode 100644 node_modules/mkdirp/test/opts_fs_sync.js create mode 100644 node_modules/mkdirp/test/perm.js create mode 100644 node_modules/mkdirp/test/perm_sync.js create mode 100644 node_modules/mkdirp/test/race.js create mode 100644 node_modules/mkdirp/test/rel.js create mode 100644 node_modules/mkdirp/test/return.js create mode 100644 node_modules/mkdirp/test/return_sync.js create mode 100644 node_modules/mkdirp/test/root.js create mode 100644 node_modules/mkdirp/test/sync.js create mode 100644 node_modules/mkdirp/test/umask.js create mode 100644 node_modules/mkdirp/test/umask_sync.js create mode 100644 node_modules/mocha/CHANGELOG.md create mode 100644 node_modules/mocha/LICENSE create mode 100644 node_modules/mocha/README.md create mode 100644 node_modules/mocha/bin/.eslintrc.yml create mode 100755 node_modules/mocha/bin/_mocha create mode 100755 node_modules/mocha/bin/mocha create mode 100644 node_modules/mocha/bin/options.js create mode 100644 node_modules/mocha/browser-entry.js create mode 100644 node_modules/mocha/images/error.png create mode 100644 node_modules/mocha/images/ok.png create mode 100644 node_modules/mocha/index.js create mode 100644 node_modules/mocha/lib/browser/.eslintrc.yml create mode 100644 node_modules/mocha/lib/browser/growl.js create mode 100644 node_modules/mocha/lib/browser/progress.js create mode 100644 node_modules/mocha/lib/browser/tty.js create mode 100644 node_modules/mocha/lib/context.js create mode 100644 node_modules/mocha/lib/hook.js create mode 100644 node_modules/mocha/lib/interfaces/bdd.js create mode 100644 node_modules/mocha/lib/interfaces/common.js create mode 100644 node_modules/mocha/lib/interfaces/exports.js create mode 100644 node_modules/mocha/lib/interfaces/index.js create mode 100644 node_modules/mocha/lib/interfaces/qunit.js create mode 100644 node_modules/mocha/lib/interfaces/tdd.js create mode 100644 node_modules/mocha/lib/mocha.js create mode 100644 node_modules/mocha/lib/ms.js create mode 100644 node_modules/mocha/lib/pending.js create mode 100644 node_modules/mocha/lib/reporters/base.js create mode 100644 node_modules/mocha/lib/reporters/doc.js create mode 100644 node_modules/mocha/lib/reporters/dot.js create mode 100644 node_modules/mocha/lib/reporters/html.js create mode 100644 node_modules/mocha/lib/reporters/index.js create mode 100644 node_modules/mocha/lib/reporters/json-stream.js create mode 100644 node_modules/mocha/lib/reporters/json.js create mode 100644 node_modules/mocha/lib/reporters/landing.js create mode 100644 node_modules/mocha/lib/reporters/list.js create mode 100644 node_modules/mocha/lib/reporters/markdown.js create mode 100644 node_modules/mocha/lib/reporters/min.js create mode 100644 node_modules/mocha/lib/reporters/nyan.js create mode 100644 node_modules/mocha/lib/reporters/progress.js create mode 100644 node_modules/mocha/lib/reporters/spec.js create mode 100644 node_modules/mocha/lib/reporters/tap.js create mode 100644 node_modules/mocha/lib/reporters/xunit.js create mode 100644 node_modules/mocha/lib/runnable.js create mode 100644 node_modules/mocha/lib/runner.js create mode 100644 node_modules/mocha/lib/suite.js create mode 100644 node_modules/mocha/lib/template.html create mode 100644 node_modules/mocha/lib/test.js create mode 100644 node_modules/mocha/lib/utils.js create mode 100644 node_modules/mocha/mocha.css create mode 100644 node_modules/mocha/mocha.js create mode 100644 node_modules/mocha/package.json create mode 100644 node_modules/ms/index.js create mode 100644 node_modules/ms/license.md create mode 100644 node_modules/ms/package.json create mode 100644 node_modules/ms/readme.md create mode 100644 node_modules/nan/CHANGELOG.md create mode 100644 node_modules/nan/LICENSE.md create mode 100644 node_modules/nan/README.md create mode 100644 node_modules/nan/doc/asyncworker.md create mode 100644 node_modules/nan/doc/buffers.md create mode 100644 node_modules/nan/doc/callback.md create mode 100644 node_modules/nan/doc/converters.md create mode 100644 node_modules/nan/doc/errors.md create mode 100644 node_modules/nan/doc/json.md create mode 100644 node_modules/nan/doc/maybe_types.md create mode 100644 node_modules/nan/doc/methods.md create mode 100644 node_modules/nan/doc/new.md create mode 100644 node_modules/nan/doc/node_misc.md create mode 100644 node_modules/nan/doc/object_wrappers.md create mode 100644 node_modules/nan/doc/persistent.md create mode 100644 node_modules/nan/doc/scopes.md create mode 100644 node_modules/nan/doc/script.md create mode 100644 node_modules/nan/doc/string_bytes.md create mode 100644 node_modules/nan/doc/v8_internals.md create mode 100644 node_modules/nan/doc/v8_misc.md create mode 100644 node_modules/nan/include_dirs.js create mode 100644 node_modules/nan/nan.h create mode 100644 node_modules/nan/nan_callbacks.h create mode 100644 node_modules/nan/nan_callbacks_12_inl.h create mode 100644 node_modules/nan/nan_callbacks_pre_12_inl.h create mode 100644 node_modules/nan/nan_converters.h create mode 100644 node_modules/nan/nan_converters_43_inl.h create mode 100644 node_modules/nan/nan_converters_pre_43_inl.h create mode 100644 node_modules/nan/nan_implementation_12_inl.h create mode 100644 node_modules/nan/nan_implementation_pre_12_inl.h create mode 100644 node_modules/nan/nan_json.h create mode 100644 node_modules/nan/nan_maybe_43_inl.h create mode 100644 node_modules/nan/nan_maybe_pre_43_inl.h create mode 100644 node_modules/nan/nan_new.h create mode 100644 node_modules/nan/nan_object_wrap.h create mode 100644 node_modules/nan/nan_persistent_12_inl.h create mode 100644 node_modules/nan/nan_persistent_pre_12_inl.h create mode 100644 node_modules/nan/nan_private.h create mode 100644 node_modules/nan/nan_string_bytes.h create mode 100644 node_modules/nan/nan_typedarray_contents.h create mode 100644 node_modules/nan/nan_weak.h create mode 100644 node_modules/nan/package.json create mode 100755 node_modules/nan/tools/1to2.js create mode 100644 node_modules/nan/tools/README.md create mode 100644 node_modules/nan/tools/package.json create mode 100644 node_modules/object-keys/.npmignore create mode 100644 node_modules/object-keys/.travis.yml create mode 100644 node_modules/object-keys/README.md create mode 100644 node_modules/object-keys/foreach.js create mode 100644 node_modules/object-keys/index.js create mode 100644 node_modules/object-keys/isArguments.js create mode 100644 node_modules/object-keys/package.json create mode 100644 node_modules/object-keys/shim.js create mode 100644 node_modules/object-keys/test/foreach.js create mode 100644 node_modules/object-keys/test/index.js create mode 100644 node_modules/object-keys/test/isArguments.js create mode 100644 node_modules/object-keys/test/shim.js create mode 100644 node_modules/once/LICENSE create mode 100644 node_modules/once/README.md create mode 100644 node_modules/once/once.js create mode 100644 node_modules/once/package.json create mode 100644 node_modules/path-is-absolute/index.js create mode 100644 node_modules/path-is-absolute/license create mode 100644 node_modules/path-is-absolute/package.json create mode 100644 node_modules/path-is-absolute/readme.md create mode 100644 node_modules/pathval/CHANGELOG.md create mode 100644 node_modules/pathval/LICENSE create mode 100644 node_modules/pathval/README.md create mode 100644 node_modules/pathval/index.js create mode 100644 node_modules/pathval/package.json create mode 100644 node_modules/pathval/pathval.js create mode 100644 node_modules/pryjs/.npmignore create mode 100644 node_modules/pryjs/.travis.yml create mode 100644 node_modules/pryjs/Gruntfile.coffee create mode 100644 node_modules/pryjs/LICENSE create mode 100644 node_modules/pryjs/assets/demo.png create mode 100755 node_modules/pryjs/bin/deploy create mode 100755 node_modules/pryjs/bin/pryjs create mode 100644 node_modules/pryjs/build/pry.js create mode 100644 node_modules/pryjs/build/pry/app.js create mode 100644 node_modules/pryjs/build/pry/command.js create mode 100644 node_modules/pryjs/build/pry/commands/continue.js create mode 100644 node_modules/pryjs/build/pry/commands/help.js create mode 100644 node_modules/pryjs/build/pry/commands/index.js create mode 100644 node_modules/pryjs/build/pry/commands/kill.js create mode 100644 node_modules/pryjs/build/pry/commands/play.js create mode 100644 node_modules/pryjs/build/pry/commands/version.js create mode 100644 node_modules/pryjs/build/pry/commands/whereami.js create mode 100644 node_modules/pryjs/build/pry/commands/wtf.js create mode 100644 node_modules/pryjs/build/pry/commands/xecute.js create mode 100644 node_modules/pryjs/build/pry/compiler.js create mode 100644 node_modules/pryjs/build/pry/file.js create mode 100644 node_modules/pryjs/build/pry/output/local_output.js create mode 100644 node_modules/pryjs/build/pry/range.js create mode 100644 node_modules/pryjs/build/pry/sync_highlight.js create mode 100644 node_modules/pryjs/build/pry/sync_prompt.js create mode 100644 node_modules/pryjs/changelog.md create mode 100644 node_modules/pryjs/code_of_conduct.md create mode 100644 node_modules/pryjs/docs/.npmignore create mode 100644 node_modules/pryjs/docs/404.md create mode 100644 node_modules/pryjs/docs/GEMFILE create mode 100644 node_modules/pryjs/docs/LICENSE create mode 100644 node_modules/pryjs/docs/README.md create mode 100644 node_modules/pryjs/docs/_config.yml create mode 100644 node_modules/pryjs/docs/_includes/disqus.html create mode 100644 node_modules/pryjs/docs/_includes/footer.html create mode 100644 node_modules/pryjs/docs/_includes/head.html create mode 100644 node_modules/pryjs/docs/_includes/header.html create mode 100644 node_modules/pryjs/docs/_includes/icons.html create mode 100644 node_modules/pryjs/docs/_layouts/default.html create mode 100644 node_modules/pryjs/docs/_layouts/home.html create mode 100644 node_modules/pryjs/docs/_layouts/page.html create mode 100644 node_modules/pryjs/docs/_layouts/post.html create mode 100644 node_modules/pryjs/docs/_sass/base/_global.scss create mode 100644 node_modules/pryjs/docs/_sass/base/_utility.scss create mode 100644 node_modules/pryjs/docs/_sass/base/_variables.scss create mode 100644 node_modules/pryjs/docs/_sass/external/_reset.scss create mode 100644 node_modules/pryjs/docs/_sass/external/_syntax.scss create mode 100644 node_modules/pryjs/docs/_sass/includes/_footer.scss create mode 100644 node_modules/pryjs/docs/_sass/includes/_header.scss create mode 100644 node_modules/pryjs/docs/_sass/layouts/_index.scss create mode 100644 node_modules/pryjs/docs/_sass/layouts/_posts.scss create mode 100644 node_modules/pryjs/docs/css/main.scss create mode 100644 node_modules/pryjs/docs/favicon.ico create mode 100644 node_modules/pryjs/docs/img/pryjs.jpg create mode 100644 node_modules/pryjs/docs/img/sample_feature_img.png create mode 100644 node_modules/pryjs/docs/img/sample_feature_img_2.png create mode 100644 node_modules/pryjs/docs/img/sample_feature_img_3.png create mode 100644 node_modules/pryjs/docs/index.md create mode 100644 node_modules/pryjs/docs/js/katex_init.js create mode 100644 node_modules/pryjs/examples/fizzbuzz.coffee create mode 100644 node_modules/pryjs/examples/fizzbuzz.js create mode 100644 node_modules/pryjs/examples/package.json create mode 100644 node_modules/pryjs/features/continue.feature create mode 100644 node_modules/pryjs/features/help.feature create mode 100644 node_modules/pryjs/features/play.feature create mode 100644 node_modules/pryjs/features/step_definitions/myStepDefinitions.coffee create mode 100644 node_modules/pryjs/features/support/after_hooks.coffee create mode 100644 node_modules/pryjs/features/support/world.coffee create mode 100644 node_modules/pryjs/features/underscore.feature create mode 100644 node_modules/pryjs/features/version.feature create mode 100644 node_modules/pryjs/features/whereami.feature create mode 100644 node_modules/pryjs/features/wtf.feature create mode 100644 node_modules/pryjs/features/xecute.feature create mode 100644 node_modules/pryjs/lib/.gitkeep create mode 100644 node_modules/pryjs/package.json create mode 100644 node_modules/pryjs/readme.md create mode 100644 node_modules/pryjs/src/pry.coffee create mode 100644 node_modules/pryjs/src/pry/app.coffee create mode 100644 node_modules/pryjs/src/pry/command.coffee create mode 100644 node_modules/pryjs/src/pry/commands/continue.coffee create mode 100644 node_modules/pryjs/src/pry/commands/help.coffee create mode 100644 node_modules/pryjs/src/pry/commands/index.coffee create mode 100644 node_modules/pryjs/src/pry/commands/kill.coffee create mode 100644 node_modules/pryjs/src/pry/commands/play.coffee create mode 100644 node_modules/pryjs/src/pry/commands/version.coffee create mode 100644 node_modules/pryjs/src/pry/commands/whereami.coffee create mode 100644 node_modules/pryjs/src/pry/commands/wtf.coffee create mode 100644 node_modules/pryjs/src/pry/commands/xecute.coffee create mode 100644 node_modules/pryjs/src/pry/compiler.coffee create mode 100644 node_modules/pryjs/src/pry/file.coffee create mode 100644 node_modules/pryjs/src/pry/output/local_output.coffee create mode 100644 node_modules/pryjs/src/pry/range.coffee create mode 100644 node_modules/pryjs/src/pry/sync_highlight.coffee create mode 100644 node_modules/pryjs/src/pry/sync_prompt.coffee create mode 100644 node_modules/pryjs/tests/app_spec.coffee create mode 100644 node_modules/pryjs/tests/command_spec.coffee create mode 100644 node_modules/pryjs/tests/commands/help_spec.coffee create mode 100644 node_modules/pryjs/tests/commands/whereami_spec.coffee create mode 100644 node_modules/pryjs/tests/compiler_spec.coffee create mode 100644 node_modules/pryjs/tests/file_spec.coffee create mode 100644 node_modules/pryjs/tests/range_spec.coffee create mode 100644 node_modules/pryjs/tests/sync_highlight_spec.coffee create mode 100644 node_modules/pygmentize-bundled/.jshintrc create mode 100644 node_modules/pygmentize-bundled/.npmignore create mode 100644 node_modules/pygmentize-bundled/LICENSE create mode 100644 node_modules/pygmentize-bundled/README.md create mode 100644 node_modules/pygmentize-bundled/index.js create mode 100644 node_modules/pygmentize-bundled/package.json create mode 100644 node_modules/pygmentize-bundled/test-fixtures/active_model.html create mode 100644 node_modules/pygmentize-bundled/test-fixtures/active_model.rb create mode 100644 node_modules/pygmentize-bundled/test.js create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/AUTHORS create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/CHANGES create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/LICENSE create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/MANIFEST.in create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/Makefile create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/TODO create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygmentize create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/__init__.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/cmdline.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/cmdline.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/console.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/console.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/filter.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/filter.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/filters/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/filters/__init__.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatter.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatter.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/__init__.pyc create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/_mapping.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/_mapping.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/bbcode.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/bbcode.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/html.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/html.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/img.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/img.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/latex.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/latex.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/other.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/other.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/rtf.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/rtf.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/svg.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/svg.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/terminal.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/terminal.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/terminal256.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/formatters/terminal256.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexer.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexer.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/__init__.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_asybuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_clbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_cocoabuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_lassobuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_luabuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_mapping.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_mapping.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_openedgebuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_phpbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_postgres_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_robotframeworklexer.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_scilab_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_sourcemodbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_stan_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/_vimbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/agile.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/agile.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/asm.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/compiled.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/compiled.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/dalvik.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/dotnet.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/foxpro.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/functional.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/functional.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/graph.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/hdl.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/inferno.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/jvm.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/jvm.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/math.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/other.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/parsers.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/qbasic.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/rdf.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/shell.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/special.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/special.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/sql.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/templates.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/text.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/web.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/lexers/web.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/modeline.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/modeline.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/plugin.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/plugin.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/scanner.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/scanner.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/sphinxext.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/style.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/style.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/__init__.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/autumn.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/borland.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/bw.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/colorful.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/default.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/default.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/emacs.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/friendly.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/fruity.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/igor.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/manni.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/monokai.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/murphy.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/native.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/paraiso_dark.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/paraiso_light.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/pastie.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/perldoc.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/rrt.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/tango.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/trac.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/vim.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/vs.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/styles/xcode.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/token.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/token.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/unistring.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/unistring.pyc create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/util.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/util.pyc create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygmentize create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/cmdline.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/console.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/filter.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/filters/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatter.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/__init__.py create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/_mapping.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/bbcode.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/html.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/img.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/latex.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/other.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/rtf.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/svg.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/terminal.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/formatters/terminal256.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexer.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_asybuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_clbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_cocoabuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_lassobuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_luabuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_mapping.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_openedgebuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_phpbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_postgres_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_robotframeworklexer.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_scilab_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_sourcemodbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_stan_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/_vimbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/agile.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/asm.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/compiled.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/dalvik.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/dotnet.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/foxpro.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/functional.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/graph.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/hdl.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/inferno.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/jvm.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/math.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/other.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/parsers.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/qbasic.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/rdf.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/shell.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/special.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/sql.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/templates.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/text.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/lexers/web.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/modeline.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/plugin.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/scanner.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/sphinxext.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/style.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/autumn.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/borland.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/bw.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/colorful.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/default.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/emacs.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/friendly.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/fruity.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/igor.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/manni.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/monokai.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/murphy.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/native.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/paraiso_dark.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/paraiso_light.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/pastie.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/perldoc.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/rrt.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/tango.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/trac.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/vim.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/vs.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/styles/xcode.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/token.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/unistring.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/build-3.3/pygments/util.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/Makefile create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_static/favicon.ico create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_static/logo_new.png create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_static/logo_only.png create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_templates/docssidebar.html create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_templates/indexsidebar.html create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/layout.html create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/bodybg.png create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/docbg.png create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/listitem.png create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/logo.png create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/pocoo.png create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/pygments14.css_t create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/theme.conf create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/conf.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/api.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/authors.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/changelog.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/cmdline.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filterdevelopment.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filters.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatterdevelopment.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatters.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/index.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/integrate.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/java.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexerdevelopment.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexers.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/moinmoin.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/plugins.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/quickstart.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/rstdirective.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/styles.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/tokens.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/docs/unicode.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/download.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/faq.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/index.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/languages.rst create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/make.bat create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/doc/pygmentize.1 create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/external/autopygmentize create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/external/lasso-builtins-generator-9.lasso create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/external/markdown-processor.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/external/moin-parser.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/external/pygments.bashcomp create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/external/rst-directive.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/ez_setup.py create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/pygmentize create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/cmdline.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/console.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/filter.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/filters/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatter.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/__init__.py create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/_mapping.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/bbcode.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/html.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/img.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/latex.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/other.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/rtf.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/svg.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/terminal.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/formatters/terminal256.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexer.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_asybuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_clbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_cocoabuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_lassobuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_luabuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_mapping.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_openedgebuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_phpbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_postgres_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_robotframeworklexer.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_scilab_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_sourcemodbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_stan_builtins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/_vimbuiltins.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/agile.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/asm.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/compiled.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/dalvik.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/dotnet.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/foxpro.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/functional.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/graph.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/hdl.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/inferno.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/jvm.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/math.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/other.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/parsers.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/qbasic.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/rdf.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/shell.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/special.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/sql.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/templates.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/text.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/lexers/web.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/modeline.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/plugin.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/scanner.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/sphinxext.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/style.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/__init__.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/autumn.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/borland.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/bw.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/colorful.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/default.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/emacs.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/friendly.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/fruity.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/igor.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/manni.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/monokai.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/murphy.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/native.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/paraiso_dark.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/paraiso_light.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/pastie.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/perldoc.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/rrt.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/tango.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/trac.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/vim.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/vs.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/styles/xcode.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/token.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/unistring.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/pygments/util.py create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/scripts/check_sources.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/scripts/detect_missing_analyse_text.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/scripts/epydoc.css create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/scripts/find_codetags.py create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/scripts/find_error.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/scripts/get_vimkw.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/scripts/pylintrc create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/scripts/vim2pygments.py create mode 100644 node_modules/pygmentize-bundled/vendor/pygments/setup.cfg create mode 100755 node_modules/pygmentize-bundled/vendor/pygments/setup.py create mode 100644 node_modules/readable-stream/.npmignore create mode 100644 node_modules/readable-stream/LICENSE create mode 100644 node_modules/readable-stream/README.md create mode 100644 node_modules/readable-stream/duplex.js create mode 100644 node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/readable-stream/package.json create mode 100644 node_modules/readable-stream/passthrough.js create mode 100644 node_modules/readable-stream/readable.js create mode 100644 node_modules/readable-stream/transform.js create mode 100644 node_modules/readable-stream/writable.js create mode 100644 node_modules/string_decoder/.npmignore create mode 100644 node_modules/string_decoder/LICENSE create mode 100644 node_modules/string_decoder/README.md create mode 100644 node_modules/string_decoder/index.js create mode 100644 node_modules/string_decoder/package.json create mode 100755 node_modules/strip-ansi/cli.js create mode 100644 node_modules/strip-ansi/index.js create mode 100644 node_modules/strip-ansi/package.json create mode 100644 node_modules/strip-ansi/readme.md create mode 100644 node_modules/supports-color/browser.js create mode 100644 node_modules/supports-color/index.js create mode 100644 node_modules/supports-color/license create mode 100644 node_modules/supports-color/package.json create mode 100644 node_modules/supports-color/readme.md create mode 100644 node_modules/through2/.jshintrc create mode 100644 node_modules/through2/.npmignore create mode 100644 node_modules/through2/.travis.yml create mode 100644 node_modules/through2/LICENSE create mode 100644 node_modules/through2/README.md create mode 100644 node_modules/through2/node_modules/readable-stream/.npmignore create mode 100644 node_modules/through2/node_modules/readable-stream/LICENSE create mode 100644 node_modules/through2/node_modules/readable-stream/README.md create mode 100644 node_modules/through2/node_modules/readable-stream/duplex.js create mode 100644 node_modules/through2/node_modules/readable-stream/float.patch create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/through2/node_modules/readable-stream/package.json create mode 100644 node_modules/through2/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/through2/node_modules/readable-stream/readable.js create mode 100644 node_modules/through2/node_modules/readable-stream/transform.js create mode 100644 node_modules/through2/node_modules/readable-stream/writable.js create mode 100644 node_modules/through2/package.json create mode 100644 node_modules/through2/test.js create mode 100644 node_modules/through2/through2.js create mode 100644 node_modules/type-detect/LICENSE create mode 100644 node_modules/type-detect/README.md create mode 100644 node_modules/type-detect/index.js create mode 100644 node_modules/type-detect/package.json create mode 100644 node_modules/type-detect/type-detect.js create mode 100644 node_modules/underscore/LICENSE create mode 100644 node_modules/underscore/README.md create mode 100644 node_modules/underscore/package.json create mode 100644 node_modules/underscore/underscore-min.js create mode 100644 node_modules/underscore/underscore-min.map create mode 100644 node_modules/underscore/underscore.js create mode 100644 node_modules/wrappy/LICENSE create mode 100644 node_modules/wrappy/README.md create mode 100644 node_modules/wrappy/package.json create mode 100644 node_modules/wrappy/wrappy.js create mode 100644 node_modules/xtend/.npmignore create mode 100644 node_modules/xtend/LICENCE create mode 100644 node_modules/xtend/Makefile create mode 100644 node_modules/xtend/README.md create mode 100644 node_modules/xtend/has-keys.js create mode 100644 node_modules/xtend/index.js create mode 100644 node_modules/xtend/mutable.js create mode 100644 node_modules/xtend/package.json create mode 100644 node_modules/xtend/test.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 rectangles.js create mode 100644 test/rectangles-test.js diff --git a/node_modules/.bin/_mocha b/node_modules/.bin/_mocha new file mode 120000 index 000000000..f2a54ffda --- /dev/null +++ b/node_modules/.bin/_mocha @@ -0,0 +1 @@ +../mocha/bin/_mocha \ No newline at end of file diff --git a/node_modules/.bin/cake b/node_modules/.bin/cake new file mode 120000 index 000000000..d95f32af4 --- /dev/null +++ b/node_modules/.bin/cake @@ -0,0 +1 @@ +../coffee-script/bin/cake \ No newline at end of file diff --git a/node_modules/.bin/coffee b/node_modules/.bin/coffee new file mode 120000 index 000000000..b57f275d7 --- /dev/null +++ b/node_modules/.bin/coffee @@ -0,0 +1 @@ +../coffee-script/bin/coffee \ No newline at end of file diff --git a/node_modules/.bin/has-ansi b/node_modules/.bin/has-ansi new file mode 120000 index 000000000..c1e7413f1 --- /dev/null +++ b/node_modules/.bin/has-ansi @@ -0,0 +1 @@ +../has-ansi/cli.js \ No newline at end of file diff --git a/node_modules/.bin/he b/node_modules/.bin/he new file mode 120000 index 000000000..2a8eb5e0c --- /dev/null +++ b/node_modules/.bin/he @@ -0,0 +1 @@ +../he/bin/he \ No newline at end of file diff --git a/node_modules/.bin/mkdirp b/node_modules/.bin/mkdirp new file mode 120000 index 000000000..017896ceb --- /dev/null +++ b/node_modules/.bin/mkdirp @@ -0,0 +1 @@ +../mkdirp/bin/cmd.js \ No newline at end of file diff --git a/node_modules/.bin/mocha b/node_modules/.bin/mocha new file mode 120000 index 000000000..43c668d9a --- /dev/null +++ b/node_modules/.bin/mocha @@ -0,0 +1 @@ +../mocha/bin/mocha \ No newline at end of file diff --git a/node_modules/.bin/pryjs b/node_modules/.bin/pryjs new file mode 120000 index 000000000..dd8b3d935 --- /dev/null +++ b/node_modules/.bin/pryjs @@ -0,0 +1 @@ +../pryjs/bin/pryjs \ No newline at end of file diff --git a/node_modules/.bin/strip-ansi b/node_modules/.bin/strip-ansi new file mode 120000 index 000000000..b65c9f81d --- /dev/null +++ b/node_modules/.bin/strip-ansi @@ -0,0 +1 @@ +../strip-ansi/cli.js \ No newline at end of file diff --git a/node_modules/ansi-regex/index.js b/node_modules/ansi-regex/index.js new file mode 100644 index 000000000..783c5c7bb --- /dev/null +++ b/node_modules/ansi-regex/index.js @@ -0,0 +1,4 @@ +'use strict'; +module.exports = function () { + return /\u001b\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]/g; +}; diff --git a/node_modules/ansi-regex/package.json b/node_modules/ansi-regex/package.json new file mode 100644 index 000000000..cdaf26e4e --- /dev/null +++ b/node_modules/ansi-regex/package.json @@ -0,0 +1,84 @@ +{ + "_from": "ansi-regex@^0.2.0", + "_id": "ansi-regex@0.2.1", + "_inBundle": false, + "_integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "_location": "/ansi-regex", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "ansi-regex@^0.2.0", + "name": "ansi-regex", + "escapedName": "ansi-regex", + "rawSpec": "^0.2.0", + "saveSpec": null, + "fetchSpec": "^0.2.0" + }, + "_requiredBy": [ + "/has-ansi", + "/strip-ansi" + ], + "_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "_shasum": "0d8e946967a3d8143f93e24e298525fc1b2235f9", + "_spec": "ansi-regex@^0.2.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/has-ansi", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/ansi-regex/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Regular expression for matching ANSI escape codes", + "devDependencies": { + "mocha": "*" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/ansi-regex#readme", + "keywords": [ + "ansi", + "styles", + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "tty", + "escape", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "text", + "regex", + "regexp", + "re", + "match", + "test", + "find", + "pattern" + ], + "license": "MIT", + "name": "ansi-regex", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/ansi-regex.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "0.2.1" +} diff --git a/node_modules/ansi-regex/readme.md b/node_modules/ansi-regex/readme.md new file mode 100644 index 000000000..ae876e729 --- /dev/null +++ b/node_modules/ansi-regex/readme.md @@ -0,0 +1,33 @@ +# ansi-regex [![Build Status](https://travis-ci.org/sindresorhus/ansi-regex.svg?branch=master)](https://travis-ci.org/sindresorhus/ansi-regex) + +> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code) + + +## Install + +```sh +$ npm install --save ansi-regex +``` + + +## Usage + +```js +var ansiRegex = require('ansi-regex'); + +ansiRegex().test('\u001b[4mcake\u001b[0m'); +//=> true + +ansiRegex().test('cake'); +//=> false + +'\u001b[4mcake\u001b[0m'.match(ansiRegex()); +//=> ['\u001b[4m', '\u001b[0m'] +``` + +*It's a function so you can create multiple instances. Regexes with the global flag will have the `.lastIndex` property changed for each call to methods on the instance. Therefore reusing the instance with multiple calls will not work as expected for `.test()`.* + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/ansi-styles/index.js b/node_modules/ansi-styles/index.js new file mode 100644 index 000000000..2d8b4726d --- /dev/null +++ b/node_modules/ansi-styles/index.js @@ -0,0 +1,40 @@ +'use strict'; +var styles = module.exports; + +var codes = { + reset: [0, 0], + + bold: [1, 22], // 21 isn't widely supported and 22 does the same thing + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], + + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49] +}; + +Object.keys(codes).forEach(function (key) { + var val = codes[key]; + var style = styles[key] = {}; + style.open = '\u001b[' + val[0] + 'm'; + style.close = '\u001b[' + val[1] + 'm'; +}); diff --git a/node_modules/ansi-styles/package.json b/node_modules/ansi-styles/package.json new file mode 100644 index 000000000..7f7df6be2 --- /dev/null +++ b/node_modules/ansi-styles/package.json @@ -0,0 +1,78 @@ +{ + "_from": "ansi-styles@^1.1.0", + "_id": "ansi-styles@1.1.0", + "_inBundle": false, + "_integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "_location": "/ansi-styles", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "ansi-styles@^1.1.0", + "name": "ansi-styles", + "escapedName": "ansi-styles", + "rawSpec": "^1.1.0", + "saveSpec": null, + "fetchSpec": "^1.1.0" + }, + "_requiredBy": [ + "/chalk" + ], + "_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "_shasum": "eaecbf66cd706882760b2f4691582b8f55d7a7de", + "_spec": "ansi-styles@^1.1.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/ansi-styles/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "ANSI escape codes for styling strings in the terminal", + "devDependencies": { + "mocha": "*" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/ansi-styles#readme", + "keywords": [ + "ansi", + "styles", + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "tty", + "escape", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "license": "MIT", + "name": "ansi-styles", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/ansi-styles.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "1.1.0" +} diff --git a/node_modules/ansi-styles/readme.md b/node_modules/ansi-styles/readme.md new file mode 100644 index 000000000..73584cc95 --- /dev/null +++ b/node_modules/ansi-styles/readme.md @@ -0,0 +1,70 @@ +# ansi-styles [![Build Status](https://travis-ci.org/sindresorhus/ansi-styles.svg?branch=master)](https://travis-ci.org/sindresorhus/ansi-styles) + +> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal + +You probably want the higher-level [chalk](https://github.com/sindresorhus/chalk) module for styling your strings. + +![screenshot](screenshot.png) + + +## Install + +```sh +$ npm install --save ansi-styles +``` + + +## Usage + +```js +var ansi = require('ansi-styles'); + +console.log(ansi.green.open + 'Hello world!' + ansi.green.close); +``` + + +## API + +Each style has an `open` and `close` property. + + +## Styles + +### General + +- `reset` +- `bold` +- `dim` +- `italic` *(not widely supported)* +- `underline` +- `inverse` +- `hidden` +- `strikethrough` *(not widely supported)* + +### Text colors + +- `black` +- `red` +- `green` +- `yellow` +- `blue` +- `magenta` +- `cyan` +- `white` +- `gray` + +### Background colors + +- `bgBlack` +- `bgRed` +- `bgGreen` +- `bgYellow` +- `bgBlue` +- `bgMagenta` +- `bgCyan` +- `bgWhite` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/assertion-error/History.md b/node_modules/assertion-error/History.md new file mode 100644 index 000000000..b240018ba --- /dev/null +++ b/node_modules/assertion-error/History.md @@ -0,0 +1,24 @@ +1.1.0 / 2018-01-02 +================== + + * Add type definitions ([#11](https://github.com/chaijs/assertion-error/pull/11)) + +1.0.1 / 2015-03-04 +================== + + * Merge pull request #2 from simonzack/master + * fixes `.stack` on firefox + +1.0.0 / 2013-06-08 +================== + + * readme: change travis and component urls + * refactor: [*] prepare for move to chaijs gh org + +0.1.0 / 2013-04-07 +================== + + * test: use vanilla test runner/assert + * pgk: remove unused deps + * lib: implement + * "Initial commit" diff --git a/node_modules/assertion-error/README.md b/node_modules/assertion-error/README.md new file mode 100644 index 000000000..6cf03c8f0 --- /dev/null +++ b/node_modules/assertion-error/README.md @@ -0,0 +1,41 @@ +# AssertionError [![Build Status](https://travis-ci.org/chaijs/assertion-error.png?branch=master)](https://travis-ci.org/chaijs/assertion-error) + +> Error constructor for test and validation frameworks that implements standardized AssertionError specification. + +## Installation + +### Node.js + +`assertion-error` is available on [npm](http://npmjs.org). + + $ npm install assertion-error + +### Component + +`assertion-error` is available as a [component](https://github.com/component/component). + + $ component install chaijs/assertion-error + +## License + +(The MIT License) + +Copyright (c) 2013 Jake Luer (http://qualiancy.com) + +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/node_modules/assertion-error/index.d.ts b/node_modules/assertion-error/index.d.ts new file mode 100644 index 000000000..2b9becdf4 --- /dev/null +++ b/node_modules/assertion-error/index.d.ts @@ -0,0 +1,11 @@ +type AssertionError = Error & T & { + showDiff: boolean; +}; + +interface AssertionErrorConstructor { + new(message: string, props?: T, ssf?: Function): AssertionError; +} + +declare const AssertionError: AssertionErrorConstructor; + +export = AssertionError; diff --git a/node_modules/assertion-error/index.js b/node_modules/assertion-error/index.js new file mode 100644 index 000000000..8466da8b2 --- /dev/null +++ b/node_modules/assertion-error/index.js @@ -0,0 +1,116 @@ +/*! + * assertion-error + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Return a function that will copy properties from + * one object to another excluding any originally + * listed. Returned function will create a new `{}`. + * + * @param {String} excluded properties ... + * @return {Function} + */ + +function exclude () { + var excludes = [].slice.call(arguments); + + function excludeProps (res, obj) { + Object.keys(obj).forEach(function (key) { + if (!~excludes.indexOf(key)) res[key] = obj[key]; + }); + } + + return function extendExclude () { + var args = [].slice.call(arguments) + , i = 0 + , res = {}; + + for (; i < args.length; i++) { + excludeProps(res, args[i]); + } + + return res; + }; +}; + +/*! + * Primary Exports + */ + +module.exports = AssertionError; + +/** + * ### AssertionError + * + * An extension of the JavaScript `Error` constructor for + * assertion and validation scenarios. + * + * @param {String} message + * @param {Object} properties to include (optional) + * @param {callee} start stack function (optional) + */ + +function AssertionError (message, _props, ssf) { + var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') + , props = extend(_props || {}); + + // default values + this.message = message || 'Unspecified AssertionError'; + this.showDiff = false; + + // copy from properties + for (var key in props) { + this[key] = props[key]; + } + + // capture stack trace + ssf = ssf || AssertionError; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, ssf); + } else { + try { + throw new Error(); + } catch(e) { + this.stack = e.stack; + } + } +} + +/*! + * Inherit from Error.prototype + */ + +AssertionError.prototype = Object.create(Error.prototype); + +/*! + * Statically set name + */ + +AssertionError.prototype.name = 'AssertionError'; + +/*! + * Ensure correct constructor + */ + +AssertionError.prototype.constructor = AssertionError; + +/** + * Allow errors to be converted to JSON for static transfer. + * + * @param {Boolean} include stack (default: `true`) + * @return {Object} object that can be `JSON.stringify` + */ + +AssertionError.prototype.toJSON = function (stack) { + var extend = exclude('constructor', 'toJSON', 'stack') + , props = extend({ name: this.name }, this); + + // include stack if exists and not turned off + if (false !== stack && this.stack) { + props.stack = this.stack; + } + + return props; +}; diff --git a/node_modules/assertion-error/package.json b/node_modules/assertion-error/package.json new file mode 100644 index 000000000..1b9a102d5 --- /dev/null +++ b/node_modules/assertion-error/package.json @@ -0,0 +1,62 @@ +{ + "_from": "assertion-error@^1.0.1", + "_id": "assertion-error@1.1.0", + "_inBundle": false, + "_integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "_location": "/assertion-error", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "assertion-error@^1.0.1", + "name": "assertion-error", + "escapedName": "assertion-error", + "rawSpec": "^1.0.1", + "saveSpec": null, + "fetchSpec": "^1.0.1" + }, + "_requiredBy": [ + "/chai" + ], + "_resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "_shasum": "e60b6b0e8f301bd97e5375215bda406c85118c0b", + "_spec": "assertion-error@^1.0.1", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/chai", + "author": { + "name": "Jake Luer", + "email": "jake@qualiancy.com", + "url": "http://qualiancy.com" + }, + "bugs": { + "url": "https://github.com/chaijs/assertion-error/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.", + "devDependencies": { + "component": "*", + "typescript": "^2.6.1" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/chaijs/assertion-error#readme", + "keywords": [ + "test", + "assertion", + "assertion-error" + ], + "license": "MIT", + "main": "./index", + "name": "assertion-error", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/chaijs/assertion-error.git" + }, + "scripts": { + "test": "make test" + }, + "types": "./index.d.ts", + "version": "1.1.0" +} diff --git a/node_modules/balanced-match/.npmignore b/node_modules/balanced-match/.npmignore new file mode 100644 index 000000000..ae5d8c36a --- /dev/null +++ b/node_modules/balanced-match/.npmignore @@ -0,0 +1,5 @@ +test +.gitignore +.travis.yml +Makefile +example.js diff --git a/node_modules/balanced-match/LICENSE.md b/node_modules/balanced-match/LICENSE.md new file mode 100644 index 000000000..2cdc8e414 --- /dev/null +++ b/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +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/node_modules/balanced-match/README.md b/node_modules/balanced-match/README.md new file mode 100644 index 000000000..08e918c0d --- /dev/null +++ b/node_modules/balanced-match/README.md @@ -0,0 +1,91 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +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/node_modules/balanced-match/index.js b/node_modules/balanced-match/index.js new file mode 100644 index 000000000..1685a7629 --- /dev/null +++ b/node_modules/balanced-match/index.js @@ -0,0 +1,59 @@ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/node_modules/balanced-match/package.json b/node_modules/balanced-match/package.json new file mode 100644 index 000000000..a7d2c3ee1 --- /dev/null +++ b/node_modules/balanced-match/package.json @@ -0,0 +1,77 @@ +{ + "_from": "balanced-match@^1.0.0", + "_id": "balanced-match@1.0.0", + "_inBundle": false, + "_integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "_location": "/balanced-match", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "balanced-match@^1.0.0", + "name": "balanced-match", + "escapedName": "balanced-match", + "rawSpec": "^1.0.0", + "saveSpec": null, + "fetchSpec": "^1.0.0" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767", + "_spec": "balanced-match@^1.0.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/brace-expansion", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/balanced-match/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "homepage": "https://github.com/juliangruber/balanced-match", + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "license": "MIT", + "main": "index.js", + "name": "balanced-match", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "scripts": { + "bench": "make bench", + "test": "make test" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.0.0" +} diff --git a/node_modules/bindings/README.md b/node_modules/bindings/README.md new file mode 100644 index 000000000..585cf512b --- /dev/null +++ b/node_modules/bindings/README.md @@ -0,0 +1,97 @@ +node-bindings +============= +### Helper module for loading your native module's .node file + +This is a helper module for authors of Node.js native addon modules. +It is basically the "swiss army knife" of `require()`ing your native module's +`.node` file. + +Throughout the course of Node's native addon history, addons have ended up being +compiled in a variety of different places, depending on which build tool and which +version of node was used. To make matters worse, now the _gyp_ build tool can +produce either a _Release_ or _Debug_ build, each being built into different +locations. + +This module checks _all_ the possible locations that a native addon would be built +at, and returns the first one that loads successfully. + + +Installation +------------ + +Install with `npm`: + +``` bash +$ npm install bindings +``` + +Or add it to the `"dependencies"` section of your _package.json_ file. + + +Example +------- + +`require()`ing the proper bindings file for the current node version, platform +and architecture is as simple as: + +``` js +var bindings = require('bindings')('binding.node') + +// Use your bindings defined in your C files +bindings.your_c_function() +``` + + +Nice Error Output +----------------- + +When the `.node` file could not be loaded, `node-bindings` throws an Error with +a nice error message telling you exactly what was tried. You can also check the +`err.tries` Array property. + +``` +Error: Could not load the bindings file. Tried: + → /Users/nrajlich/ref/build/binding.node + → /Users/nrajlich/ref/build/Debug/binding.node + → /Users/nrajlich/ref/build/Release/binding.node + → /Users/nrajlich/ref/out/Debug/binding.node + → /Users/nrajlich/ref/Debug/binding.node + → /Users/nrajlich/ref/out/Release/binding.node + → /Users/nrajlich/ref/Release/binding.node + → /Users/nrajlich/ref/build/default/binding.node + → /Users/nrajlich/ref/compiled/0.8.2/darwin/x64/binding.node + at bindings (/Users/nrajlich/ref/node_modules/bindings/bindings.js:84:13) + at Object. (/Users/nrajlich/ref/lib/ref.js:5:47) + at Module._compile (module.js:449:26) + at Object.Module._extensions..js (module.js:467:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + ... +``` + + +License +------- + +(The MIT License) + +Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net> + +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/node_modules/bindings/bindings.js b/node_modules/bindings/bindings.js new file mode 100644 index 000000000..93dcf85a1 --- /dev/null +++ b/node_modules/bindings/bindings.js @@ -0,0 +1,166 @@ + +/** + * Module dependencies. + */ + +var fs = require('fs') + , path = require('path') + , join = path.join + , dirname = path.dirname + , exists = fs.existsSync || path.existsSync + , defaults = { + arrow: process.env.NODE_BINDINGS_ARROW || ' → ' + , compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled' + , platform: process.platform + , arch: process.arch + , version: process.versions.node + , bindings: 'bindings.node' + , try: [ + // node-gyp's linked version in the "build" dir + [ 'module_root', 'build', 'bindings' ] + // node-waf and gyp_addon (a.k.a node-gyp) + , [ 'module_root', 'build', 'Debug', 'bindings' ] + , [ 'module_root', 'build', 'Release', 'bindings' ] + // Debug files, for development (legacy behavior, remove for node v0.9) + , [ 'module_root', 'out', 'Debug', 'bindings' ] + , [ 'module_root', 'Debug', 'bindings' ] + // Release files, but manually compiled (legacy behavior, remove for node v0.9) + , [ 'module_root', 'out', 'Release', 'bindings' ] + , [ 'module_root', 'Release', 'bindings' ] + // Legacy from node-waf, node <= 0.4.x + , [ 'module_root', 'build', 'default', 'bindings' ] + // Production "Release" buildtype binary (meh...) + , [ 'module_root', 'compiled', 'version', 'platform', 'arch', 'bindings' ] + ] + } + +/** + * The main `bindings()` function loads the compiled bindings for a given module. + * It uses V8's Error API to determine the parent filename that this function is + * being invoked from, which is then used to find the root directory. + */ + +function bindings (opts) { + + // Argument surgery + if (typeof opts == 'string') { + opts = { bindings: opts } + } else if (!opts) { + opts = {} + } + opts.__proto__ = defaults + + // Get the module root + if (!opts.module_root) { + opts.module_root = exports.getRoot(exports.getFileName()) + } + + // Ensure the given bindings name ends with .node + if (path.extname(opts.bindings) != '.node') { + opts.bindings += '.node' + } + + var tries = [] + , i = 0 + , l = opts.try.length + , n + , b + , err + + for (; inew BufferList([ callback ]) + * bl.length + * bl.append(buffer) + * bl.get(index) + * bl.slice([ start[, end ] ]) + * bl.consume(bytes) + * bl.toString([encoding, [ start, [ end ]]]) + * bl.readDoubleBE(), bl.readDoubleLE(), bl.readFloatBE(), bl.readFloatLE(), bl.readInt32BE(), bl.readInt32LE(), bl.readUInt32BE(), bl.readUInt32LE(), bl.readInt16BE(), bl.readInt16LE(), bl.readUInt16BE(), bl.readUInt16LE(), bl.readInt8(), bl.readUInt8() + * Streams + +-------------------------------------------------------- + +### new BufferList([ callback | buffer | buffer array ]) +The constructor takes an optional callback, if supplied, the callback will be called with an error argument followed by a reference to the **bl** instance, when `bl.end()` is called (i.e. from a piped stream). This is a convenient method of collecting the entire contents of a stream, particularly when the stream is *chunky*, such as a network stream. + +Normally, no arguments are required for the constructor, but you can initialise the list by passing in a single `Buffer` object or an array of `Buffer` object. + +`new` is not strictly required, if you don't instantiate a new object, it will be done automatically for you so you can create a new instance simply with: + +```js +var bl = require('bl') +var myinstance = bl() + +// equivilant to: + +var BufferList = require('bl') +var myinstance = new BufferList() +``` + +-------------------------------------------------------- + +### bl.length +Get the length of the list in bytes. This is the sum of the lengths of all of the buffers contained in the list, minus any initial offset for a semi-consumed buffer at the beginning. Should accurately represent the total number of bytes that can be read from the list. + +-------------------------------------------------------- + +### bl.append(buffer) +`append(buffer)` adds an additional buffer to the internal list. + +-------------------------------------------------------- + +### bl.get(index) +`get()` will return the byte at the specified index. + +-------------------------------------------------------- + +### bl.slice([ start, [ end ] ]) +`slice()` returns a new `Buffer` object containing the bytes within the range specified. Both `start` and `end` are optional and will default to the beginning and end of the list respectively. + +If the requested range spans a single internal buffer then a slice of that buffer will be returned which shares the original memory range of that Buffer. If the range spans multiple buffers then copy operations will likely occur to give you a uniform Buffer. + +-------------------------------------------------------- + +### bl.consume(bytes) +`consume()` will shift bytes *off the start of the list*. The number of bytes consumed don't need to line up with the sizes of the internal Buffers—initial offsets will be calculated accordingly in order to give you a consistent view of the data. + +-------------------------------------------------------- + +### bl.toString([encoding, [ start, [ end ]]]) +`toString()` will return a string representation of the buffer. The optional `start` and `end` arguments are passed on to `slice()`, while the `encoding` is passed on to `toString()` of the resulting Buffer. See the [Buffer#toString()](http://nodejs.org/docs/latest/api/buffer.html#buffer_buf_tostring_encoding_start_end) documentation for more information. + +-------------------------------------------------------- + +### bl.readDoubleBE(), bl.readDoubleLE(), bl.readFloatBE(), bl.readFloatLE(), bl.readInt32BE(), bl.readInt32LE(), bl.readUInt32BE(), bl.readUInt32LE(), bl.readInt16BE(), bl.readInt16LE(), bl.readUInt16BE(), bl.readUInt16LE(), bl.readInt8(), bl.readUInt8() + +All of the standard byte-reading methods of the `Buffer` interface are implemented and will operate across internal Buffer boundaries transparently. + +See the [Buffer](http://nodejs.org/docs/latest/api/buffer.html) documentation for how these work. + +-------------------------------------------------------- + +### Streams +**bl** is a Node **[Duplex Stream](http://nodejs.org/docs/latest/api/stream.html#stream_class_stream_duplex)**, so it can be read from and written to like a standard Node stream. You can also `pipe()` to and from a **bl** instance. + +## Contributors + +**bl** is brought to you by the following hackers: + + * [Rod Vagg](https://github.com/rvagg) + * [Matteo Collina](https://github.com/mcollina) + +## License + +**bl** is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. diff --git a/node_modules/bl/bl.js b/node_modules/bl/bl.js new file mode 100644 index 000000000..8cf1c76be --- /dev/null +++ b/node_modules/bl/bl.js @@ -0,0 +1,157 @@ +const DuplexStream = require('stream').DuplexStream || require('readable-stream/duplex') + , util = require('util') + +function BufferList (callback) { + if (!(this instanceof BufferList)) + return new BufferList(callback) + + this._bufs = [] + this.length = 0 + + if (typeof callback == 'function') + this._callback = callback + else if (Buffer.isBuffer(callback)) + this.append(callback) + else if (Array.isArray(callback)) { + callback.forEach(function (b) { + Buffer.isBuffer(b) && this.append(b) + }.bind(this)) + } + + DuplexStream.call(this) +} + +util.inherits(BufferList, DuplexStream) + +BufferList.prototype._offset = function (offset) { + var tot = 0, i = 0, _t + for (; i < this._bufs.length; i++) { + _t = tot + this._bufs[i].length + if (offset < _t) + return [ i, offset - tot ] + tot = _t + } +} + +BufferList.prototype.append = function (buf) { + this._bufs.push(Buffer.isBuffer(buf) ? buf : new Buffer(buf)) + this.length += buf.length + return this +} + +BufferList.prototype._write = function (buf, encoding, callback) { + this.append(buf) + if (callback) + callback() +} + +BufferList.prototype._read = function (size) { + if (!this.length) + return this.push(null) + size = Math.min(size, this.length) + this.push(this.slice(0, size)) + this.consume(size) +} + +BufferList.prototype.end = function (chunk) { + DuplexStream.prototype.end.call(this, chunk) + + if (this._callback) + this._callback(null, this.slice()) +} + +BufferList.prototype.get = function (index) { + return this.slice(index, index + 1)[0] +} + +BufferList.prototype.slice = function (start, end) { + if (typeof start != 'number' || start < 0) + start = 0 + if (typeof end != 'number' || end > this.length) + end = this.length + if (start >= this.length) + return new Buffer(0) + if (end <= 0) + return new Buffer(0) + + if (start === 0 && end == this.length) + return Buffer.concat(this._bufs) + + var off = this._offset(start) + , len = end - start + , bytes = len + , bufoff = 0 + , buf, l, i + + start = off[1] + + // easy, cheap case where it's a subset of one of the buffers + if (bytes <= this._bufs[off[0]].length - start) + return this._bufs[off[0]].slice(start, start + bytes) + + buf = new Buffer(len) + + for (i = off[0]; i < this._bufs.length; i++) { + l = this._bufs[i].length - start + if (bytes > l) { + this._bufs[i].copy(buf, bufoff, start) + } else { + this._bufs[i].copy(buf, bufoff, start, start + bytes) + break + } + + bufoff += l + bytes -= l + + if (start) + start = 0 + } + + return buf +} + +BufferList.prototype.toString = function (encoding, start, end) { + return this.slice(start, end).toString(encoding) +} + +BufferList.prototype.consume = function (bytes) { + while (this._bufs.length) { + if (bytes > this._bufs[0].length) { + bytes -= this._bufs[0].length + this.length -= this._bufs[0].length + this._bufs.shift() + } else { + this._bufs[0] = this._bufs[0].slice(bytes) + this.length -= bytes + break + } + } + return this +} + +;(function () { + var methods = { + 'readDoubleBE' : 8 + , 'readDoubleLE' : 8 + , 'readFloatBE' : 4 + , 'readFloatLE' : 4 + , 'readInt32BE' : 4 + , 'readInt32LE' : 4 + , 'readUInt32BE' : 4 + , 'readUInt32LE' : 4 + , 'readInt16BE' : 2 + , 'readInt16LE' : 2 + , 'readUInt16BE' : 2 + , 'readUInt16LE' : 2 + , 'readInt8' : 1 + , 'readUInt8' : 1 + } + + Object.keys(methods).forEach(function (m) { + BufferList.prototype[m] = function (offset) { + return this.slice(offset, offset + methods[m])[m](0) + } + }) +}()) + +module.exports = BufferList diff --git a/node_modules/bl/package.json b/node_modules/bl/package.json new file mode 100644 index 000000000..987e22318 --- /dev/null +++ b/node_modules/bl/package.json @@ -0,0 +1,60 @@ +{ + "_from": "bl@~0.4.1", + "_id": "bl@0.4.2", + "_inBundle": false, + "_integrity": "sha1-XbMdcvA4xU5orcOVeBJf47Ct3JY=", + "_location": "/bl", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "bl@~0.4.1", + "name": "bl", + "escapedName": "bl", + "rawSpec": "~0.4.1", + "saveSpec": null, + "fetchSpec": "~0.4.1" + }, + "_requiredBy": [ + "/pygmentize-bundled" + ], + "_resolved": "https://registry.npmjs.org/bl/-/bl-0.4.2.tgz", + "_shasum": "5db31d72f038c54e68adc39578125fe3b0addc96", + "_spec": "bl@~0.4.1", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/pygmentize-bundled", + "authors": [ + "Rod Vagg (https://github.com/rvagg)", + "Matteo Collina (https://github.com/mcollina)" + ], + "bugs": { + "url": "https://github.com/rvagg/bl/issues" + }, + "bundleDependencies": false, + "dependencies": { + "readable-stream": "~1.0.2" + }, + "deprecated": false, + "description": "Buffer List: collect buffers and access with a standard readable Buffer interface, streamable too!", + "devDependencies": { + "hash_file": "*", + "tape": "*" + }, + "homepage": "https://github.com/rvagg/bl", + "keywords": [ + "buffer", + "buffers", + "stream", + "awesomesauce" + ], + "license": "MIT", + "main": "bl.js", + "name": "bl", + "repository": { + "type": "git", + "url": "git+https://github.com/rvagg/bl.git" + }, + "scripts": { + "test": "tape test.js" + }, + "version": "0.4.2" +} diff --git a/node_modules/bl/test.js b/node_modules/bl/test.js new file mode 100644 index 000000000..cbea7bad5 --- /dev/null +++ b/node_modules/bl/test.js @@ -0,0 +1,356 @@ +const tape = require('tape') + , crypto = require('crypto') + , fs = require('fs') + , hash = require('hash_file') + , BufferList = require('./') + +tape('single bytes from single buffer', function (t) { + var bl = new BufferList() + bl.append(new Buffer('abcd')) + + t.equal(bl.length, 4) + + t.equal(bl.get(0), 97) + t.equal(bl.get(1), 98) + t.equal(bl.get(2), 99) + t.equal(bl.get(3), 100) + + t.end() +}) + +tape('single bytes from multiple buffers', function (t) { + var bl = new BufferList() + bl.append(new Buffer('abcd')) + bl.append(new Buffer('efg')) + bl.append(new Buffer('hi')) + bl.append(new Buffer('j')) + + t.equal(bl.length, 10) + + t.equal(bl.get(0), 97) + t.equal(bl.get(1), 98) + t.equal(bl.get(2), 99) + t.equal(bl.get(3), 100) + t.equal(bl.get(4), 101) + t.equal(bl.get(5), 102) + t.equal(bl.get(6), 103) + t.equal(bl.get(7), 104) + t.equal(bl.get(8), 105) + t.equal(bl.get(9), 106) + t.end() +}) + +tape('multi bytes from single buffer', function (t) { + var bl = new BufferList() + bl.append(new Buffer('abcd')) + + t.equal(bl.length, 4) + + t.equal(bl.slice(0, 4).toString('ascii'), 'abcd') + t.equal(bl.slice(0, 3).toString('ascii'), 'abc') + t.equal(bl.slice(1, 4).toString('ascii'), 'bcd') + + t.end() +}) + +tape('multiple bytes from multiple buffers', function (t) { + var bl = new BufferList() + + bl.append(new Buffer('abcd')) + bl.append(new Buffer('efg')) + bl.append(new Buffer('hi')) + bl.append(new Buffer('j')) + + t.equal(bl.length, 10) + + t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij') + t.equal(bl.slice(3, 10).toString('ascii'), 'defghij') + t.equal(bl.slice(3, 6).toString('ascii'), 'def') + t.equal(bl.slice(3, 8).toString('ascii'), 'defgh') + t.equal(bl.slice(5, 10).toString('ascii'), 'fghij') + + t.end() +}) + +tape('consuming from multiple buffers', function (t) { + var bl = new BufferList() + + bl.append(new Buffer('abcd')) + bl.append(new Buffer('efg')) + bl.append(new Buffer('hi')) + bl.append(new Buffer('j')) + + t.equal(bl.length, 10) + + t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij') + + bl.consume(3) + t.equal(bl.length, 7) + t.equal(bl.slice(0, 7).toString('ascii'), 'defghij') + + bl.consume(2) + t.equal(bl.length, 5) + t.equal(bl.slice(0, 5).toString('ascii'), 'fghij') + + bl.consume(1) + t.equal(bl.length, 4) + t.equal(bl.slice(0, 4).toString('ascii'), 'ghij') + + bl.consume(1) + t.equal(bl.length, 3) + t.equal(bl.slice(0, 3).toString('ascii'), 'hij') + + bl.consume(2) + t.equal(bl.length, 1) + t.equal(bl.slice(0, 1).toString('ascii'), 'j') + + t.end() +}) + +tape('test readUInt8 / readInt8', function (t) { + var buf1 = new Buffer(1) + , buf2 = new Buffer(3) + , buf3 = new Buffer(3) + , bl = new BufferList() + + buf2[1] = 0x3 + buf2[2] = 0x4 + buf3[0] = 0x23 + buf3[1] = 0x42 + + bl.append(buf1) + bl.append(buf2) + bl.append(buf3) + + t.equal(bl.readUInt8(2), 0x3) + t.equal(bl.readInt8(2), 0x3) + t.equal(bl.readUInt8(3), 0x4) + t.equal(bl.readInt8(3), 0x4) + t.equal(bl.readUInt8(4), 0x23) + t.equal(bl.readInt8(4), 0x23) + t.equal(bl.readUInt8(5), 0x42) + t.equal(bl.readInt8(5), 0x42) + t.end() +}) + +tape('test readUInt16LE / readUInt16BE / readInt16LE / readInt16BE', function (t) { + var buf1 = new Buffer(1) + , buf2 = new Buffer(3) + , buf3 = new Buffer(3) + , bl = new BufferList() + + buf2[1] = 0x3 + buf2[2] = 0x4 + buf3[0] = 0x23 + buf3[1] = 0x42 + + bl.append(buf1) + bl.append(buf2) + bl.append(buf3) + + t.equal(bl.readUInt16BE(2), 0x0304) + t.equal(bl.readUInt16LE(2), 0x0403) + t.equal(bl.readInt16BE(2), 0x0304) + t.equal(bl.readInt16LE(2), 0x0403) + t.equal(bl.readUInt16BE(3), 0x0423) + t.equal(bl.readUInt16LE(3), 0x2304) + t.equal(bl.readInt16BE(3), 0x0423) + t.equal(bl.readInt16LE(3), 0x2304) + t.equal(bl.readUInt16BE(4), 0x2342) + t.equal(bl.readUInt16LE(4), 0x4223) + t.equal(bl.readInt16BE(4), 0x2342) + t.equal(bl.readInt16LE(4), 0x4223) + t.end() +}) + +tape('test readUInt32LE / readUInt32BE / readInt32LE / readInt32BE', function (t) { + var buf1 = new Buffer(1) + , buf2 = new Buffer(3) + , buf3 = new Buffer(3) + , bl = new BufferList() + + buf2[1] = 0x3 + buf2[2] = 0x4 + buf3[0] = 0x23 + buf3[1] = 0x42 + + bl.append(buf1) + bl.append(buf2) + bl.append(buf3) + + t.equal(bl.readUInt32BE(2), 0x03042342) + t.equal(bl.readUInt32LE(2), 0x42230403) + t.equal(bl.readInt32BE(2), 0x03042342) + t.equal(bl.readInt32LE(2), 0x42230403) + t.end() +}) + +tape('test readFloatLE / readFloatBE', function (t) { + var buf1 = new Buffer(1) + , buf2 = new Buffer(3) + , buf3 = new Buffer(3) + , bl = new BufferList() + + buf2[1] = 0x00 + buf2[2] = 0x00 + buf3[0] = 0x80 + buf3[1] = 0x3f + + bl.append(buf1) + bl.append(buf2) + bl.append(buf3) + + t.equal(bl.readFloatLE(2), 0x01) + t.end() +}) + +tape('test readDoubleLE / readDoubleBE', function (t) { + var buf1 = new Buffer(1) + , buf2 = new Buffer(3) + , buf3 = new Buffer(10) + , bl = new BufferList() + + buf2[1] = 0x55 + buf2[2] = 0x55 + buf3[0] = 0x55 + buf3[1] = 0x55 + buf3[2] = 0x55 + buf3[3] = 0x55 + buf3[4] = 0xd5 + buf3[5] = 0x3f + + bl.append(buf1) + bl.append(buf2) + bl.append(buf3) + + t.equal(bl.readDoubleLE(2), 0.3333333333333333) + t.end() +}) + +tape('test toString', function (t) { + var bl = new BufferList() + + bl.append(new Buffer('abcd')) + bl.append(new Buffer('efg')) + bl.append(new Buffer('hi')) + bl.append(new Buffer('j')) + + t.equal(bl.toString('ascii', 0, 10), 'abcdefghij') + t.equal(bl.toString('ascii', 3, 10), 'defghij') + t.equal(bl.toString('ascii', 3, 6), 'def') + t.equal(bl.toString('ascii', 3, 8), 'defgh') + t.equal(bl.toString('ascii', 5, 10), 'fghij') + + t.end() +}) + +tape('test toString encoding', function (t) { + var bl = new BufferList() + , b = new Buffer('abcdefghij\xff\x00') + + bl.append(new Buffer('abcd')) + bl.append(new Buffer('efg')) + bl.append(new Buffer('hi')) + bl.append(new Buffer('j')) + bl.append(new Buffer('\xff\x00')) + + 'hex utf8 utf-8 ascii binary base64 ucs2 ucs-2 utf16le utf-16le' + .split(' ') + .forEach(function (enc) { + t.equal(bl.toString(enc), b.toString(enc)) + }) + + t.end() +}) + +tape('test stream', function (t) { + var random = crypto.randomBytes(1024 * 1024) + , rndhash = hash(random, 'md5') + , md5sum = crypto.createHash('md5') + , bl = new BufferList(function (err, buf) { + t.ok(Buffer.isBuffer(buf)) + t.ok(err === null) + t.equal(rndhash, hash(bl.slice(), 'md5')) + t.equal(rndhash, hash(buf, 'md5')) + + bl.pipe(fs.createWriteStream('/tmp/bl_test_rnd_out.dat')) + .on('close', function () { + var s = fs.createReadStream('/tmp/bl_test_rnd_out.dat') + s.on('data', md5sum.update.bind(md5sum)) + s.on('end', function() { + t.equal(rndhash, md5sum.digest('hex'), 'woohoo! correct hash!') + t.end() + }) + }) + + }) + + fs.writeFileSync('/tmp/bl_test_rnd.dat', random) + fs.createReadStream('/tmp/bl_test_rnd.dat').pipe(bl) +}) + +tape('instantiation with Buffer', function (t) { + var buf = crypto.randomBytes(1024) + , buf2 = crypto.randomBytes(1024) + , b = BufferList(buf) + + t.equal(hash(buf, 'md5'), hash(b.slice(), 'md5'), 'same hash!') + b = BufferList([ buf, buf2 ]) + t.equal(hash(b.slice(), 'md5'), hash(Buffer.concat([ buf, buf2 ]), 'md5'), 'same hash!') + t.end() +}) + +tape('test String appendage', function (t) { + var bl = new BufferList() + , b = new Buffer('abcdefghij\xff\x00') + + bl.append('abcd') + bl.append('efg') + bl.append('hi') + bl.append('j') + bl.append('\xff\x00') + + 'hex utf8 utf-8 ascii binary base64 ucs2 ucs-2 utf16le utf-16le' + .split(' ') + .forEach(function (enc) { + t.equal(bl.toString(enc), b.toString(enc)) + }) + + t.end() +}) + +tape('write nothing, should get empty buffer', function (t) { + t.plan(3) + BufferList(function (err, data) { + t.notOk(err, 'no error') + t.ok(Buffer.isBuffer(data), 'got a buffer') + t.equal(0, data.length, 'got a zero-length buffer') + t.end() + }).end() +}) + +tape('unicode string', function (t) { + t.plan(2) + var inp1 = '\u2600' + , inp2 = '\u2603' + , exp = inp1 + ' and ' + inp2 + , bl = BufferList() + bl.write(inp1) + bl.write(' and ') + bl.write(inp2) + t.equal(exp, bl.toString()) + t.equal(new Buffer(exp).toString('hex'), bl.toString('hex')) +}) + +tape('should emit finish', function (t) { + var source = BufferList() + , dest = BufferList() + + source.write('hello') + source.pipe(dest) + + dest.on('finish', function () { + t.equal(dest.toString('utf8'), 'hello') + t.end() + }) +}) diff --git a/node_modules/brace-expansion/LICENSE b/node_modules/brace-expansion/LICENSE new file mode 100644 index 000000000..de3226673 --- /dev/null +++ b/node_modules/brace-expansion/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013 Julian Gruber + +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/node_modules/brace-expansion/README.md b/node_modules/brace-expansion/README.md new file mode 100644 index 000000000..6b4e0e164 --- /dev/null +++ b/node_modules/brace-expansion/README.md @@ -0,0 +1,129 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) +[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## Sponsors + +This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! + +Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +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/node_modules/brace-expansion/index.js b/node_modules/brace-expansion/index.js new file mode 100644 index 000000000..0478be81e --- /dev/null +++ b/node_modules/brace-expansion/index.js @@ -0,0 +1,201 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/node_modules/brace-expansion/package.json b/node_modules/brace-expansion/package.json new file mode 100644 index 000000000..fa7289121 --- /dev/null +++ b/node_modules/brace-expansion/package.json @@ -0,0 +1,75 @@ +{ + "_from": "brace-expansion@^1.1.7", + "_id": "brace-expansion@1.1.11", + "_inBundle": false, + "_integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "_location": "/brace-expansion", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "brace-expansion@^1.1.7", + "name": "brace-expansion", + "escapedName": "brace-expansion", + "rawSpec": "^1.1.7", + "saveSpec": null, + "fetchSpec": "^1.1.7" + }, + "_requiredBy": [ + "/minimatch" + ], + "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "_shasum": "3c7fcbf529d87226f3d2f52b966ff5271eb441dd", + "_spec": "brace-expansion@^1.1.7", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/minimatch", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/brace-expansion/issues" + }, + "bundleDependencies": false, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "deprecated": false, + "description": "Brace expansion as known from sh/bash", + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "homepage": "https://github.com/juliangruber/brace-expansion", + "keywords": [], + "license": "MIT", + "main": "index.js", + "name": "brace-expansion", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "scripts": { + "bench": "matcha test/perf/bench.js", + "gentest": "bash test/generate.sh", + "test": "tape test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.1.11" +} diff --git a/node_modules/browser-stdout/LICENSE b/node_modules/browser-stdout/LICENSE new file mode 100644 index 000000000..775f6cef6 --- /dev/null +++ b/node_modules/browser-stdout/LICENSE @@ -0,0 +1,5 @@ +Copyright 2018 kumavis + +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/node_modules/browser-stdout/README.md b/node_modules/browser-stdout/README.md new file mode 100644 index 000000000..f32028ad9 --- /dev/null +++ b/node_modules/browser-stdout/README.md @@ -0,0 +1,40 @@ +### wat? + +`process.stdout` in your browser. + +### wai? + +iono. cuz hakz. + +### hau? + +```js +var BrowserStdout = require('browser-stdout') + +myStream.pipe(BrowserStdout()) +``` + +### monkey + +You can monkey-patch `process.stdout` for your dependency graph like this: + +``` +process.stdout = require('browser-stdout')() +var coolTool = require('module-that-uses-stdout-somewhere-in-its-depths') +``` + +### opts + +opts are passed directly to `stream.Writable`. +additionally, a label arg can be used to label console output. + +```js +BrowserStdout({ + objectMode: true, + label: 'dataz', +}) +``` + +### ur doin it rong + +i accept pr's. \ No newline at end of file diff --git a/node_modules/browser-stdout/index.js b/node_modules/browser-stdout/index.js new file mode 100644 index 000000000..daf39c3b6 --- /dev/null +++ b/node_modules/browser-stdout/index.js @@ -0,0 +1,25 @@ +var WritableStream = require('stream').Writable +var inherits = require('util').inherits + +module.exports = BrowserStdout + + +inherits(BrowserStdout, WritableStream) + +function BrowserStdout(opts) { + if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts) + + opts = opts || {} + WritableStream.call(this, opts) + this.label = (opts.label !== undefined) ? opts.label : 'stdout' +} + +BrowserStdout.prototype._write = function(chunks, encoding, cb) { + var output = chunks.toString ? chunks.toString() : chunks + if (this.label === false) { + console.log(output) + } else { + console.log(this.label+':', output) + } + process.nextTick(cb) +} diff --git a/node_modules/browser-stdout/package.json b/node_modules/browser-stdout/package.json new file mode 100644 index 000000000..7e1af4fdd --- /dev/null +++ b/node_modules/browser-stdout/package.json @@ -0,0 +1,46 @@ +{ + "_from": "browser-stdout@1.3.1", + "_id": "browser-stdout@1.3.1", + "_inBundle": false, + "_integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "_location": "/browser-stdout", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "browser-stdout@1.3.1", + "name": "browser-stdout", + "escapedName": "browser-stdout", + "rawSpec": "1.3.1", + "saveSpec": null, + "fetchSpec": "1.3.1" + }, + "_requiredBy": [ + "/mocha" + ], + "_resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "_shasum": "baa559ee14ced73452229bad7326467c61fabd60", + "_spec": "browser-stdout@1.3.1", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/mocha", + "author": { + "name": "kumavis" + }, + "bugs": { + "url": "https://github.com/kumavis/browser-stdout/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "`process.stdout` in your browser.", + "homepage": "https://github.com/kumavis/browser-stdout#readme", + "license": "ISC", + "main": "index.js", + "name": "browser-stdout", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/kumavis/browser-stdout.git" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "version": "1.3.1" +} diff --git a/node_modules/chai/.npmignore b/node_modules/chai/.npmignore new file mode 100644 index 000000000..59f495632 --- /dev/null +++ b/node_modules/chai/.npmignore @@ -0,0 +1,14 @@ +.git* +docs/ +test/ +support/ +component.json +components/ +build/ +lib-cov/ +coverage/ +.travis.yml +.mailmap +Makefile +*.swp +.DS_Store diff --git a/node_modules/chai/CODEOWNERS b/node_modules/chai/CODEOWNERS new file mode 100644 index 000000000..ea74b66ed --- /dev/null +++ b/node_modules/chai/CODEOWNERS @@ -0,0 +1 @@ +* @chaijs/chai diff --git a/node_modules/chai/CODE_OF_CONDUCT.md b/node_modules/chai/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..074addcc2 --- /dev/null +++ b/node_modules/chai/CODE_OF_CONDUCT.md @@ -0,0 +1,58 @@ +# Contributor Code of Conduct + +> Read in: [Español](http://contributor-covenant.org/version/1/3/0/es/) | +[Français](http://contributor-covenant.org/version/1/3/0/fr/) | +[Italiano](http://contributor-covenant.org/version/1/3/0/it/) | +[Magyar](http://contributor-covenant.org/version/1/3/0/hu/) | +[Polskie](http://contributor-covenant.org/version/1/3/0/pl/) | +[Português](http://contributor-covenant.org/version/1/3/0/pt/) | +[Português do Brasil](http://contributor-covenant.org/version/1/3/0/pt_br/) + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer at chaijs@keithcirkel.co.uk. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. Maintainers are +obligated to maintain confidentiality with regard to the reporter of an +incident. + + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ diff --git a/node_modules/chai/CONTRIBUTING.md b/node_modules/chai/CONTRIBUTING.md new file mode 100644 index 000000000..78e2ce435 --- /dev/null +++ b/node_modules/chai/CONTRIBUTING.md @@ -0,0 +1,218 @@ +# Chai Contribution Guidelines + +We like to encourage you to contribute to the Chai.js repository. This should be as easy as possible for you but there are a few things to consider when contributing. The following guidelines for contribution should be followed if you want to submit a pull request or open an issue. + +Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. + +#### Table of Contents + +- [TLDR;](#tldr) +- [Contributing](#contributing) + - [Bug Reports](#bugs) + - [Feature Requests](#features) + - [Pull Requests](#pull-requests) +- [Releasing](#releasing) +- [Support](#support) + - [Resources](#resources) + - [Core Contributors](#contributors) + + +## TLDR; + +- Creating an Issue or Pull Request requires a [GitHub](http://github.com) account. +- Issue reports should be **clear**, **concise** and **reproducible**. Check to see if your issue has already been resolved in the [master]() branch or already reported in Chai's [GitHub Issue Tracker](https://github.com/chaijs/chai/issues). +- Pull Requests must adhere to strict [coding style guidelines](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide). +- In general, avoid submitting PRs for new Assertions without asking core contributors first. More than likely it would be better implemented as a plugin. +- Additional support is available via the [Google Group](http://groups.google.com/group/chaijs) or on irc.freenode.net#chaijs. +- **IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. + + + + +## Contributing + +The issue tracker is the preferred channel for [bug reports](#bugs), +[feature requests](#features) and [submitting pull +requests](#pull-requests), but please respect the following restrictions: + +* Please **do not** use the issue tracker for personal support requests (use + [Google Group](https://groups.google.com/forum/#!forum/chaijs) or IRC). +* Please **do not** derail or troll issues. Keep the discussion on topic and + respect the opinions of others + + +### Bug Reports + +A bug is a **demonstrable problem** that is caused by the code in the repository. + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been reported. +2. **Check if the issue has been fixed** — try to reproduce it using the latest `master` or development branch in the repository. +3. **Isolate the problem** — create a test case to demonstrate your issue. Provide either a repo, gist, or code sample to demonstrate you problem. + +A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What browser(s) and/or Node.js versions experience the problem? What would you expect to be the outcome? All these details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the browser/OS environment in which it occurs. If suitable, include the steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` - a link to the reduced test case OR +> ```js +> expect(a).to.equal('a'); +> // code sample +> ``` +> +> Any other information you want to share that is relevant to the issue being reported. This might include the lines of code that you have identified as causing the bug, and potential solutions (and your opinions on their merits). + + +### Feature Requests + +Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible. + +Furthermore, since Chai.js has a [robust plugin API](http://chaijs.com/guide/plugins/), we encourage you to publish **new Assertions** as plugins. If your feature is an enhancement to an **existing Assertion**, please propose your changes as an issue prior to opening a pull request. If the core Chai.js contributors feel your plugin would be better suited as a core assertion, they will invite you to open a PR in [chaijs/chai](https://github.com/chaijs/chai). + + +### Pull Requests + +- PRs for new core-assertions are advised against. +- PRs for core-assertion bug fixes are always welcome. +- PRs for enhancing the interfaces are always welcome. +- PRs that increase test coverage are always welcome. +- PRs are scrutinized for coding-style. + +Good pull requests - patches, improvements, new features - are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. + +**Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. + +Please adhere to the coding conventions used throughout a project (indentation, accurate comments, etc.) and any other requirements (such as test coverage). Please review the [Chai.js Coding Style Guide](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide). + +Follow this process if you'd like your work considered for inclusion in the project: + +1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes: + +```bash +# Clone your fork of the repo into the current directory +git clone https://github.com// +# Navigate to the newly cloned directory +cd +# Assign the original repo to a remote called "upstream" +git remote add upstream https://github.com// +``` + +2. If you cloned a while ago, get the latest changes from upstream: + +```bash +git checkout +git pull upstream +``` + +3. Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: + +```bash +git checkout -b +``` + +4. Commit your changes in logical chunks. Use Git's [interactive rebase](https://help.github.com/articles/interactive-rebase) feature to tidy up your commits before making them public. + +5. Run you code to make sure it works. If you're still having problems please try to run `make clean` and then test your code again. + +```bash +npm test +# when finished running tests... +git checkout chai.js +``` + +6. Locally merge (or rebase) the upstream development branch into your topic branch: + +```bash +git pull [--rebase] upstream +``` + +7. Push your topic branch up to your fork: + +```bash +git push origin +``` + +8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description. + +**IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. + + +## Releasing + +Releases can be **prepared** by anyone with access to the code. + +Simply run `make release-major`, `make release-minor`, or `make-release-patch` +and it will automatically do the following: + + - Build chai.js + - Bump the version numbers accross the project + - Make a commit within git + +All you need to do is push the commit up and make a pull request, one of the core contributors will merge it and publish a release. + +### Publishing a Release + +Anyone who is a core contributor (see the [Core Contributors Heading in the Readme](https://github.com/chaijs/chai#core-contributors)) can publish a release: + +1. Go to te [Releases page on Github](https://github.com/chaijs/chai/releases) +2. Hit "Draft a new release" (if you can't see this, you're not a core contributor!) +3. Write human-friendly Release Notes based on changelog. + - The release title is "x.x.x / YYYY-MM-DD" (where x.x.x is the version number) + - If breaking changes, write migration tutorial(s) and reasoning. + - Callouts for community contributions (PRs) with links to PR and contributing user. + - Callouts for other fixes made by core contributors with links to issue. +4. Hit "Save Draft" and get other core contributors to check your work, or alternatively hit "Publish release" +5. That's it! + + +## Support + + +### Resources + +For most of the documentation you are going to want to visit [ChaiJS.com](http://chaijs.com). + +- [Getting Started Guide](http://chaijs.com/guide/) +- [API Reference](http://chaijs.com/api/) +- [Plugins](http://chaijs.com/plugins/) + +Alternatively, the [wiki](https://github.com/chaijs/chai/wiki) might be what you are looking for. + +- [Chai Coding Style Guide](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide) +- [Third-party Resources](https://github.com/chaijs/chai/wiki/Third-Party-Resources) + +Or finally, you may find a core-contributor or like-minded developer in any of our support channels. + +- IRC: irc.freenode.org #chaijs +- [Mailing List / Google Group](https://groups.google.com/forum/#!forum/chaijs) + + +### Core Contributors + +Feel free to reach out to any of the core-contributors with you questions or concerns. We will do our best to respond in a timely manner. + +- Jake Luer + - GH: [@logicalparadox](https://github.com/logicalparadox) + - TW: [@jakeluer](http://twitter.com/jakeluer) + - IRC: logicalparadox +- Veselin Todorov + - GH: [@vesln](https://github.com/vesln/) + - TW: [@vesln](http://twitter.com/vesln) + - IRC: vesln +- Keith Cirkel + - GH: [@keithamus](https://github.com/keithamus) + - TW: [@keithamus](http://twitter.com/keithamus) + - IRC: keithamus +- Lucas Fernandes da Costa + - GH: [@lucasfcosta](https://github.com/lucasfcosta) + - TW: [@lfernandescosta](https://twitter.com/lfernandescosta) + - IRC: lucasfcosta diff --git a/node_modules/chai/History.md b/node_modules/chai/History.md new file mode 100644 index 000000000..ae4d323e7 --- /dev/null +++ b/node_modules/chai/History.md @@ -0,0 +1,1059 @@ +### Note + +As of 3.0.0, the History.md file has been deprecated. [Please refer to the full +commit logs available on GitHub](https://github.com/chaijs/chai/commits/master). + +--- + +2.3.0 / 2015-04-26 +================== + + * Merge pull request #423 from ehntoo/patch-1 + * Merge pull request #422 from ljharb/fix_descriptor_tests + * Fix a small bug in the .null assertion docs + * Use a regex to account for property ordering issues across engines. + * Add `make test-firefox` + * Merge pull request #417 from astorije/astorije/minimalist-typo + * Remove trailing whitespaces + * Fix super minor typo in an example + * Merge pull request #408 from ljharb/enumerableProperty + * Add `ownPropertyDescriptor` assertion. + +2.2.0 / 2015-03-26 +================== + + * Merge pull request #405 from chaijs/deep-escape-doc-tweaks + * Tweak documentation on `.deep` flag. + * Merge pull request #402 from umireon/escaping-dot-should-be-taken + * Documentation of escaping in `.deep` flag. + * take regular expression apart + * Feature: backslash-escaping in `.deep.property` + * Escaping dot should be taken in deep property + +2.1.2 / 2015-03-15 +================== + + * Merge pull request #396 from chaijs/add-keith-cirkel-contributing-md + * Add Keith Cirkel to CONTRIBUTING.md + * Merge pull request #395 from cjqed/386-assert-operator-no-eval + * No longer using eval on assert operator #386 + * Merge pull request #389 from chaijs/update-git-summary + * Update `git summary` in README + +2.1.1 / 2015-03-04 +================== + + * Merge pull request #385 from eldritch-fossicker/master + * updates to reflect code style preference from @keithamus + * fix indexing into array with deep propery + * Merge pull request #382 from astorije/patch-2 + * Merge pull request #383 from gurdiga/config-doc-wording-improvement + * config.truncateThreshold docs: simpler wording + * Add missing docstring for showDiff argument of assert + * Merge pull request #381 from astorije/patch-1 + * Add a minor precision that empty asserts on strings too. + * Merge pull request #379 from dcneiner/should-primitive-fix + * Primitives now use valueOf in shouldGetter + +2.1.0 / 2015-02-23 +================== + + * Merge pull request #374 from jmm/v2.0.1 + * Increment version to 2.0.1. + * Merge pull request #365 from chaijs/fix-travis + * Fix travis.yml deploy + * Merge pull request #356 from Soviut/master + * documented fail methods for expect and should interfaces + * fail method added directly to expect + +2.0.0 / 2015-02-09 +================== + + * Merge pull request #361 from gregglind/b265-keys-object + * fix #359. Add `.keys(object)` + * Merge pull request #359 from gregglind/b359-unexpected-keys-sort + * Fix #359 keys() sorts input unexpectedly + * contrib: publish release strategy and travis npm creds #337 + * Merge pull request #357 from danilovaz/master + * Update copyright date + * Merge pull request #349 from toastynerd/add-which-chain-method + * add the which chain method as per issue #347 + * Merge pull request #333 from cmpolis/change-assertions + * more `by` cleanup + * cleaned out `.by` for #333 + * Merge pull request #335 from DingoEatingFuzz/expose-util + * Expose chai util through the chai object + * cleanup (per notes on pr #333) + * updated `change` to work w/ non-number values + tests + * Merge pull request #334 from hurrymaplelad/patch-1 + * Typo, the flag is called 'contains' with an 's' + * updated assertion interface with `change` (#330) + * added `change`,`increase`,`decrease` assertions (#330) + * assert tests for `change`,`increase`,`decrease` + * expect/should tests for `change`,`increase`,`decrease` + * Merge pull request #328 from lo1tuma/issue-327 + * Add includes and contains alias (fixes #327) + * Merge pull request #325 from chasenlehara/overwriteChainableMethodDocs + * Fix docs for overwriteChainableMethod parameters + * Merge pull request #317 from jasonkarns/patch-2 + * Merge pull request #318 from jasonkarns/patch-3 + * Merge pull request #316 from jasonkarns/patch-1 + * typos in docs + * minor docs typo + * update docs: getAllFlags -> transferFlags + * Merge pull request #313 from cjqed/254-expect-any-all + * Added the all and any flags for keys assertion, with all being the default behavior + * Merge pull request #312 from cjqed/291-assert-same-deep-members + * Changed public comment of sameDeepMemebers to be more clear + * Fixes issue #291, adds assert.sameDeepMembers + * Merge pull request #311 from cjqed/305-above-below-on-assert + * Merge pull request #308 from prodatakey/hasproperty + * Issue #305 fixed, added assert.isAbove and assert.isBelow + * Fix typo + * More unit tests for new utility functions + * Refactor common functionality, document, test + * Refactor if statement out + * Small unit test fix + * Handle array indexing terminating paths + * Merge pull request #309 from ericdouglas/iterableEqual-couting-once + * couting variables just once + * Fix properties with `undefined` value pass property assertion + * Merge pull request #306 from chaijs/revert-297-noopchainfunc + * Revert "Allows writing lint-friendly tests" + +1.10.0 / 2014-11-10 +================== + + * Merge pull request #297 from prodatakey/noopchainfunc + * Merge pull request #300 from julienw/299-fix-getMessage-test + * Fix #299: the test is defining global variables + * Add a couple more unit tests + * Add unit tests for chained terminating property asserts + * Revise documentation wording + * Add docs for function style NOOP asserts + * Make the NOOP function a shared constant + * Merge pull request #298 from dasilvacontin/negativeZeroLogging + * why not more assertions + * added test for inspecting `-0` + * a more readable/simple condition statement, as pointed out by @keithamus + * added check for logging negative zero + * Change test to not trigger argument bug + * Allows writing lint-friendly tests + * readme: update contributors for 1.9.2 + +1.9.2 / 2014-09-29 +================== + + * Merge pull request #268 from charlierudolph/cr-lazyMessages + * Merge pull request #269 from charlierudolph/cr-codeCleanup + * Merge pull request #277 from charlierudolph/fix-doc + * Merge pull request #279 from mohayonao/fix-closeTo + * Merge pull request #292 from boneskull/mocha + * resolves #255: upgrade mocha + * Merge pull request #289 from charlierudolph/cr-dryUpCode + * Dry up code + * Merge pull request #275 from DrRataplan/master + * assert: .closeTo() verify value's type before assertion + * Rewrite pretty-printing HTML elements to prevent throwing internal errors Fixes errors occuring when using a non-native DOM implementation + * Fix assert documentation + * Remove unused argument + * Allow messages to be functions + * Merge pull request #267 from shinnn/master + * Use SVG badge + * Merge pull request #264 from cjthompson/keys_diff + * Show diff for keys assertion + +1.9.1 / 2014-03-19 +================== + + * deps update + * util: [getActual] select actual logic now allows undefined for actual. Closes #183 + * docs: [config] make public, express param type + * Merge pull request #251 from romario333/threshold3 + * Fix issue #166 - configurable threshold in objDisplay. + * Move configuration options to config.js. + * Merge pull request #233 from Empeeric/master + * Merge pull request #244 from leider/fix_for_contains + * Merge pull request #247 from didoarellano/typo-fixes + * Fix typos + * Merge pull request #245 from lfac-pt/patch-1 + * Update `exports.version` to 1.9.0 + * aborting loop on finding + * declaring variable only once + * additional test finds incomplete implementation + * simplified code + * fixing #239 (without changing chai.js) + * ssfi as it should be + * Merge pull request #228 from duncanbeevers/deep_members + * Deep equality check for collection membership + +1.9.0 / 2014-01-29 +================== + + * docs: add contributing.md #238 + * assert: .throws() returns thrown error. Closes #185 + * Merge pull request #232 from laconbass/assert-throws + * assert: .fail() parameter mismatch. Closes #206 + * Merge branch 'karma-fixes' + * Add karma phantomjs launcher + * Use latest karma and sauce launcher + * Karma tweaks + * Merge pull request #230 from jkroso/include + * Merge pull request #237 from chaijs/coverage + * Add coverage to npmignore + * Remove lib-cov from test-travisci dependents + * Remove the not longer needed lcov reporter + * Test coverage with istanbul + * Remove jscoverage + * Remove coveralls + * Merge pull request #226 from duncanbeevers/add_has + * Avoid error instantiation if possible on assert.throws + * Merge pull request #231 from duncanbeevers/update_copyright_year + * Update Copyright notices to 2014 + * handle negation correctly + * add failing test case + * support `{a:1,b:2}.should.include({a:1})` + * Merge pull request #224 from vbardales/master + * Add `has` to language chains + * Merge pull request #219 from demands/overwrite_chainable + * return error on throw method to chain on error properties, possibly different from message + * util: store chainable behavior in a __methods object on ctx + * util: code style fix + * util: add overwriteChainableMethod utility (for #215) + * Merge pull request #217 from demands/test_cleanup + * test: make it possible to run utilities tests with --watch + * makefile: change location of karma-runner bin script + * Merge pull request #202 from andreineculau/patch-2 + * test: add tests for throwing custom errors + * Merge pull request #201 from andreineculau/patch-1 + * test: updated for the new assertion errors + * core: improve message for assertion errors (throw assertion) + +1.8.1 / 2013-10-10 +================== + + * pkg: update deep-eql version + +1.8.0 / 2013-09-18 +================== + + * test: [sauce] add a few more browsers + * Merge branch 'refactor/deep-equal' + * util: remove embedded deep equal utility + * util: replace embedded deep equal with external module + * Merge branch 'feature/karma' + * docs: add sauce badge to readme [ci skip] + * test: [sauce] use karma@canary to prevent timeouts + * travis: only run on node 0.10 + * test: [karma] use karma phantomjs runner + * Merge pull request #181 from tricknotes/fix-highlight + * Fix highlight for example code + +1.7.2 / 2013-06-27 +================== + + * coverage: add coveralls badge + * test: [coveralls] add coveralls api integration. testing travis-ci integration + * Merge branch 'master' of github.com:chaijs/chai + * Merge branch 'feature/bower' + * Merge pull request #180 from tricknotes/modify-method-title + * Merge pull request #179 from tricknotes/highlight-code-example + * Modify method title to include argument name + * Fix to highlight code example + * bower: granular ignores + +1.7.1 / 2013-06-24 +================== + + * Merge branch 'feature/bower'. #175 + * bower: add json file + * build: browser + +1.7.0 / 2013-06-17 +================== + + * error: remove internal assertion error constructor + * core: [assertion-error] replace internal assertion error with dep + * deps: add chaijs/assertion-error@1.0.0 + * docs: fix typo in source file. #174 + * Merge pull request #174 from piecioshka/master + * typo + * Merge branch 'master' of github.com:chaijs/chai + * pkg: lock mocha/mocha-phantomjs versions (for now) + * Merge pull request #173 from chaijs/inspect-fix + * Fix `utils.inspect` with custom object-returning inspect()s. + * Merge pull request #171 from Bartvds/master + * replaced tabs with 2 spaces + * added assert.notOk() + * Merge pull request #169 from katsgeorgeek/topics/master + * Fix comparison objects. + +1.6.1 / 2013-06-05 +================== + + * Merge pull request #168 from katsgeorgeek/topics/master + * Add test for different RegExp flags. + * Add test for regexp comparison. + * Downgrade mocha version for fix running Phantom tests. + * Fix comparison equality of two regexps. + * Merge pull request #161 from brandonpayton/master + * Fix documented name for assert interfaces isDefined method + +1.6.0 / 2013-04-29 +================== + + * build: browser + * assert: [(not)include] throw on incompatible haystack. Closes #142 + * assert: [notInclude] add assert.notInclude. Closes #158 + * browser build + * makefile: force browser build on browser-test + * makefile: use component for browser build + * core: [assertions] remove extraneous comments + * Merge branch 'master' of github.com:chaijs/chai + * test: [assert] deep equal ordering + * Merge pull request #153 from NickHeiner/array-assertions + * giving members a no-flag assertion + * Code review comments - changing syntax + * Code review comments + * Adding members and memberEquals assertions for checking for subsets and set equality. Implements chaijs/chai#148. + * Merge pull request #140 from RubenVerborgh/function-prototype + * Restore the `call` and `apply` methods of Function when adding a chainable method. + * readme: 2013 + * notes: migration notes for deep equal changes + * test: for ever err() there must be a passing version + +1.5.0 / 2013-02-03 +================== + + * docs: add Release Notes for non-gitlog summary of changes. + * lib: update copyright to 2013 + * Merge branch 'refactor/travis' + * makefile: remove test-component for full test run + * pkg: script test now runs make test so travis will test browser + * browser: build + * tests: refactor some tests to support new objDisplay output + * test: [bootstrap] normalize boostrap across all test scenarios + * assertions: refactor some assertions to use objDisplay instead of inspect + * util: [objDisplay] normalize output of functions + * makefile: refactor for full build scenarios + * component: fix build bug where missing util:type file + * assertions: [throw] code cleanup + * Merge branch 'refactor/typeDetection' + * browser: build + * makefile: chai.js is .PHONY so it builds every time + * test: [expect] add arguments type detection test + * core/assertions: [type] (a/an) refactor to use type detection utility + * util: add cross-browser type detection utility + * Merge branch 'feature/component' + * browser: build + * component: add component.json file + * makefile: refactor for fine grain control of testing scenarios + * test: add mochaPhantomJS support and component test file + * deps: add component and mocha-phantomjs for browser testing + * ignore: update ignore files for component support + * travis: run for all branches + * Merge branch 'feature/showDiff' + * test: [Assertion] configruable showDiff flag. Closes #132 + * lib: [Assertion] add configurable showDiff flag. #132 + * Merge branch 'feature/saucelabs' + * Merge branch 'master' into feature/saucelabs + * browser: build + * support: add mocha cloud runner, client, and html test page + * test: [saucelabs] add auth placeholder + * deps: add mocha-cloud + * Merge pull request #136 from whatthejeff/message_fix + * Merge pull request #138 from timnew/master + * Fix issue #137, test message existence by using message!=null rather than using message + * Fixed backwards negation messages. + * Merge pull request #133 from RubenVerborgh/throw + * Functions throwing strings can reliably be tested. + * Merge pull request #131 from RubenVerborgh/proto + * Cache whether __proto__ is supported. + * Use __proto__ if available. + * Determine the property names to exclude beforehand. + * Merge pull request #126 from RubenVerborgh/eqls + * Add alias eqls for eql. + * Use inherited enumerable properties in deep equality comparison. + * Show inherited properties when inspecting an object. + * Add new getProperties and getEnumerableProperties utils. + * showDiff: force true for equal and eql + +1.4.2 / 2012-12-21 +================== + + * browser build: (object diff support when used with mocha) #106 + * test: [display] array test for mocha object diff + * browser: no longer need different AssertionError constructor + +1.4.1 / 2012-12-21 +================== + + * showDiff: force diff for equal and eql. #106 + * test: [expect] type null. #122 + * Merge pull request #115 from eshao/fix-assert-Throw + * FIX: assert.Throw checks error type/message + * TST: assert.Throw should check error type/message + +1.4.0 / 2012-11-29 +================== + + * pre-release browser build + * clean up index.js to not check for cov, revert package.json to use index.js + * convert tests to use new bootstrap + * refactor testing bootstrap + * use spaces (not tabs). Clean up #114 + * Merge pull request #114 from trantorLiu/master + * Add most() (alias: lte) and least() (alias: gte) to the API with new chainers "at" and "of". + * Change `main` to ./lib/chai. Fixes #28. + * Merge pull request #104 from connec/deep_equals_circular_references_ + * Merge pull request #109 from nnarhinen/patch-1 + * Check for 'actual' type + * Added support for circular references when checking deep (in)equality. + +1.3.0 / 2012-10-01 +================== + + * browser build w/ folio >= 0.3.4. Closes #99 + * add back buffer test for deep equal + * do not write flags to assertion.prototype + * remove buffer test from expect + * browser build + * improve documentation of custom error messages + * Merge branch 'master' of git://github.com/Liffft/chai into Liffft-master + * browser build + * improved buffer deep equal checking + * mocha is npm test command + * Cleaning up the js style… + * expect tests now include message pass-through + * packaging up browser-side changes… + * Increasing Throws error message verbosity + * Should syntax: piping message through + * Make globalShould test work in browser too. + * Add a setter for `Object.prototype.should`. Closes #86. + +1.2.0 / 2012-08-07 +================== + + * Merge branch 'feature/errmsg' + * browser build + * comment updates for utilities + * tweak objDislay to only kick in if object inspection is too long + * Merge branch 'master' into feature/errmsg + * add display sample for error message refactor + * first draft of error message refactor. #93 + * add `closeTo` assertion to `assert` interface. Closes #89. + * update folio build for better require.js handling. Closes #85 + * Merge pull request #92 from paulmillr/topics/add-dom-checks + * Add check for DOM objects. + * browser build + * Merge branch 'master' of github.com:chaijs/chai + * bug - getActual not defaulting to assertion subject + * Merge pull request #88 from pwnall/master + * Don't inspect() assertion arguments if the assertion passes. + +1.1.1 / 2012-07-09 +================== + + * improve commonjs support on browser build + * Merge pull request #83 from tkazec/equals + * Document .equals + * Add .equals as an alias of .equal + * remove unused browser prefix/suffix + * Merge branch 'feature/folio-build' + * browser build + * using folio to compile + * clean up makefile + * early folio 0.3.x support + +1.1.0 / 2012-06-26 +================== + + * browser build + * Disable "Assertion.includeStack is false" test in IE. + * Use `utils.getName` for all function inspections. + * Merge pull request #80 from kilianc/closeTo + * fixes #79 + * browser build + * expand docs to indicate change of subject for chaining. Closes #78 + * add `that` chain noop + * Merge branch 'bug/74' + * comments on how to property use `length` as chain. Closes #74 + * tests for length as chainable property. #74 + * add support for `length` as chainable prop/method. + * Merge branch 'bug/77' + * tests for getPathValue when working with nested arrays. Closes #77 + * add getPathValue support for nested arrays + * browser build + * fix bug for missing browser utils + * compile tool aware of new folder layout + * Merge branch 'refactor/1dot1' + * move core assertions to own file and refactor all using utils + * rearrange folder structure + +1.0.4 / 2012-06-03 +================== + + * Merge pull request #68 from fizker/itself + * Added itself chain. + * simplify error inspections for cross browser compatibility + * fix safari `addChainableMethod` errors. Closes #69 + +1.0.3 / 2012-05-27 +================== + + * Point Travis badge to the right place. + * Make error message for eql/deep.equal more clear. + * Fix .not.deep.equal. + * contributors list + +1.0.2 / 2012-05-26 +================== + + * Merge pull request #67 from chaijs/chaining-and-flags + * Browser build. + * Use `addChainableMethod` to get away from `__proto__` manipulation. + * New `addChainableMethod` utility. + * Replace `getAllFlags` with `transferFlags` utility. + * browser build + * test - get all flags + * utility - get all flags + * Add .mailmap to .npmignore. + * Add a .mailmap file to fix my name in shortlogs. + +1.0.1 / 2012-05-18 +================== + + * browser build + * Fixing "an" vs. "a" grammar in type assertions. + * Uniformize `assert` interface inline docs. + * Don't use `instanceof` for `assert.isArray`. + * Add `deep` flag for equality and property value. + * Merge pull request #64 from chaijs/assertion-docs + * Uniformize assertion inline docs. + * Add npm-debug.log to .gitignore. + * no reserved words as actuals. #62 + +1.0.0 / 2012-05-15 +================== + + * readme cleanup + * browser build + * utility comments + * removed docs + * update to package.json + * docs build + * comments / docs updates + * plugins app cleanup + * Merge pull request #61 from joliss/doc + * Fix and improve documentation of assert.equal and friends + * browser build + * doc checkpoint - texture + * Update chai-jquery link + * Use defined return value of Assertion extension functions + * Update utility docs + +1.0.0-rc3 / 2012-05-09 +================== + + * Merge branch 'feature/rc3' + * docs update + * browser build + * assert test conformity for minor refactor api + * assert minor refactor + * update util tests for new add/overwrite prop/method format + * added chai.Assertion.add/overwrite prop/method for plugin toolbox + * add/overwrite prop/method don't make assumptions about context + * doc test suite + * docs don't need coverage + * refactor all simple chains into one forEach loop, for clean documentation + * updated npm ignore + * remove old docs + * docs checkpoint - guide styled + * Merge pull request #59 from joliss/doc + * Document how to run the test suite + * don't need to rebuild docs to view + * dep update + * docs checkpoint - api section + * comment updates for docs + * new doc site checkpoint - plugin directory! + * Merge pull request #57 from kossnocorp/patch-1 + * Fix typo: devDependancies → devDependencies + * Using message flag in `getMessage` util instead of old `msg` property. + * Adding self to package.json contributors. + * `getMessage` shouldn't choke on null/omitted messages. + * `return this` not necessary in example. + * `return this` not necessary in example. + * Sinon–Chai has a dash + * updated plugins list for docs + +1.0.0-rc2 / 2012-05-06 +================== + + * Merge branch 'feature/test-cov' + * browser build + * missing assert tests for ownProperty + * appropriate assert equivalent for expect.to.have.property(key, val) + * reset AssertionError to include full stack + * test for plugin utilities + * overwrite Property and Method now ensure chain + * version notes in readme + +1.0.0-rc1 / 2012-05-04 +================== + + * browser build (rc1) + * assert match/notMatch tests + * assert interface - notMatch, ownProperty, notOwnProperty, ownPropertyVal, ownPropertyNotVal + * cleaner should interface export. + * added chai.Assertion.prototype._obj (getter) for quick access to object flag + * moved almostEqual / almostDeepEqual to stats plugin + * added mocha.opts + * Add test for `utils.addMethod` + * Fix a typo + * Add test for `utils.overwriteMethod` + * Fix a typo + * Browser build + * Add undefined assertion + * Add null assertion + * Fix an issue with `mocha --watch` + * travis no longer tests on node 0.4.x + * removing unnecissary carbon dep + * Merge branch 'feature/plugins-app' + * docs build + * templates for docs express app for plugin directory + * express app for plugin and static serving + * added web server deps + * Merge pull request #54 from josher19/master + * Remove old test.assert code + * Use util.inspect instead of inspect for deepAlmostEqual and almostEqual + * browser build + * Added almostEqual and deepAlmostEqual to assert test suite. + * bug - context determinants for utils + * dec=0 means rounding, so assert.deepAlmostEqual({pi: 3.1416}, {pi: 3}, 0) is true + * wrong travis link + * readme updates for version information + * travis tests 0.5.x branch as well + * [bug] util `addProperty` not correctly exporting + * read me version notes + * browser build 1.0.0alpha1 + * not using reserved words in internal assertions. #52 + * version tick + * clean up redundant tests + * Merge branch 'refs/heads/0.6.x' + * update version tag in package 1.0.0alpha1 + * browser build + * added utility tests to browser specs + * beginning utility testing + * updated utility comments + * utility - overwriteMethod + * utility - overwriteProperty + * utility - addMethod + * utility - addProperty + * missing ; + * contributors list update + * Merge branch 'refs/heads/0.6.x-docs' into 0.6.x + * Added guide link to docs. WIP + * Include/contain are now both properties and methods + * Add an alias annotation + * Remove usless function wrapper + * Fix a typo + * A/an are now both properties and methods + * [docs] new site homepage layout / color checkpoint + * Ignore IE-specific error properties. + * Fixing order of error message test. + * New cross-browser `getName` util. + * Fixing up `AssertionError` inheritance. + * backup docs + * Add doctypes + * [bug] was still using `constructor.name` in `throw` assertion + * [bug] flag Object.create(null) instead of new Object + * [test] browser build + * [refactor] all usage of Assertion.prototype.assert now uses template tags and flags + * [refactor] remove Assertion.prototype.inspect for testable object inspection + * [refactor] object to test is now stored in flag, with ssfi and custom message + * [bug] flag util - don't return on `set` + * [docs] comments for getMessage utility + * [feature] getMessage + * [feature] testing utilities + * [refactor] flag doesn't require `call` + * Make order of source files well-defined + * Added support for throw(errorInstance). + * Use a foolproof method of grabbing an error's name. + * Removed constructor.name check from throw. + * disabled stackTrack configuration tests until api is stable again + * first version of line displayed error for node js (unstable) + * refactor core Assertion to use flag utility for negation + * added flag utility + * tests for assert interface negatives. Closed #42 + * added assertion negatives that were missing. #42 + * Support for expected and actual parameters in assert-style error object + * chai as promised - readme + * Added assert.fail. Closes #40 + * better error message for assert.operator. Closes #39 + * [refactor] Assertion#property to use getPathValue property + * added getPathValue utility helper + * removed todo about browser build + * version notes + * version bumb 0.6.0 + * browser build + * [refactor] browser compile function to replace with `require('./error')' with 'require('./browser/error')' + * [feature] browser uses different error.js + * [refactor] error without chai.fail + * Assertion & interfaces use new utils helper export + * [refactor] primary export for new plugin util usage + * added util index.js helper + * added 2012 to copyright headers + * Added DeepEqual assertions + +0.5.3 / 2012-04-21 +================== + + * Merge branch 'refs/heads/jgonera-oldbrowsers' + * browser build + * fixed reserved names for old browsers in interface/assert + * fixed reserved names for old browsers in interface/should + * fixed: chai.js no longer contains fail() + * fixed reserved names for old browsers in Assertion + * Merge pull request #49 from joliss/build-order + * Make order of source files well-defined + * Merge pull request #43 from zzen/patch-1 + * Support for expected and actual parameters in assert-style error object + * chai as promised - readme + +0.5.2 / 2012-03-21 +================== + + * browser build + * Merge branch 'feature/assert-fail' + * Added assert.fail. Closes #40 + * Merge branch 'bug/operator-msg' + * better error message for assert.operator. Closes #39 + * version notes + +0.5.1 / 2012-03-14 +================== + + * chai.fail no longer exists + * Merge branch 'feature/assertdefined' + * Added asset#isDefined. Closes #37. + * dev docs update for Assertion#assert + +0.5.0 / 2012-03-07 +================== + + * [bug] on inspect of reg on n 0.4.12 + * Merge branch 'bug/33-throws' + * Merge pull request #35 from logicalparadox/empty-object + * browser build + * updated #throw docs + * Assertion#throw `should` tests updated + * Assertion#throw `expect` tests + * Should interface supports multiple throw parameters + * Update Assertion#throw to support strings and type checks. + * Add more tests for `empty` in `should`. + * Add more tests for `empty` in `expect`. + * Merge branch 'master' into empty-object + * don't switch act/exp + * Merge pull request #34 from logicalparadox/assert-operator + * Update the compiled verison. + * Add `assert.operator`. + * Notes on messages. #22 + * browser build + * have been test + * below tests + * Merge branch 'feature/actexp' + * browser build + * remove unnecessary fail export + * full support for actual/expected where relevant + * Assertion.assert support expected value + * clean up error + * Update the compiled version. + * Add object & sane arguments support to `Assertion#empty`. + +0.4.2 / 2012-02-28 +================== + + * fix for `process` not available in browser when used via browserify. Closes #28 + * Merge pull request #31 from joliss/doc + * Document that "should" works in browsers other than IE + * Merge pull request #30 from logicalparadox/assert-tests + * Update the browser version of chai. + * Update `assert.doesNotThrow` test in order to check the use case when type is a string. + * Add test for `assert.ifError`. + * Falsey -> falsy. + * Full coverage for `assert.throws` and `assert.doesNotThrow`. + * Add test for `assert.doesNotThrow`. + * Add test for `assert.throws`. + * Add test for `assert.length`. + * Add test for `assert.include`. + * Add test for `assert.isBoolean`. + * Fix the implementation of `assert.isNumber`. + * Add test for `assert.isNumber`. + * Add test for `assert.isString`. + * Add test for `assert.isArray`. + * Add test for `assert.isUndefined`. + * Add test for `assert.isNotNull`. + * Fix `assert.isNotNull` implementation. + * Fix `assert.isNull` implementation. + * Add test for `assert.isNull`. + * Add test for `assert.notDeepEqual`. + * Add test for `assert.deepEqual`. + * Add test for `assert.notStrictEqual`. + * Add test for `assert.strictEqual`. + * Add test for `assert.notEqual`. + +0.4.1 / 2012-02-26 +================== + + * Merge pull request #27 from logicalparadox/type-fix + * Update the browser version. + * Add should tests for type checks. + * Add function type check test. + * Add more type checks tests. + * Add test for `new Number` type check. + * Fix type of actual checks. + +0.4.0 / 2012-02-25 +================== + + * docs and readme for upcoming 0.4.0 + * docs generated + * putting coverage and tests for docs in docs/out/support + * make docs + * makefile copy necessary resources for tests in docs + * rename configuration test + * Merge pull request #21 from logicalparadox/close-to + * Update the browser version. + * Update `closeTo()` docs. + * Add `Assertion.closeTo()` method. + * Add `.closeTo()` should test. + * Add `.closeTo()` expect test. + * Merge pull request #20 from logicalparadox/satisfy + * Update the browser version. + * `..` -> `()` in `.satisfy()` should test. + * Update example for `.satisfy()`. + * Update the compiled browser version. + * Add `Assertion.satisfy()` method. + * Add `.satisfy()` should test. + * Add `.satisfy()` expect test. + * Merge pull request #19 from logicalparadox/respond-to + * Update the compiled browser version. + * Add `respondTo` Assertion. + * Add `respondTo` should test. + * Add `respondTo` expect test. + * Merge branch 'feature/coverage' + * mocha coverage support + * doc contributors + * README contributors + +0.3.4 / 2012-02-23 +================== + + * inline comment typos for #15 + * Merge branch 'refs/heads/jeffbski-configErrorStackCompat' + * includeStack documentation for all interfaces + * suite name more generic + * Update test to be compatible with browsers that do not support err.stack + * udpated compiled chai.js and added to browser tests + * Allow inclusion of stack trace for Assert error messages to be configurable + * docs sharing buttons + * sinon-chai link + * doc updates + * read me updates include plugins + +0.3.3 / 2012-02-12 +================== + + * Merge pull request #14 from jfirebaugh/configurable_properties + * Make Assertion.prototype properties configurable + +0.3.2 / 2012-02-10 +================== + + * codex version + * docs + * docs cleanup + +0.3.1 / 2012-02-07 +================== + + * node 0.4.x compat + +0.3.0 / 2012-02-07 +================== + + * Merge branch 'feature/03x' + * browser build + * remove html/json/headers testign + * regex error.message testing + * tests for using plugins + * Merge pull request #11 from domenic/master + * Make `chai.use` a no-op if the function has already been used. + +0.2.4 / 2012-02-02 +================== + + * added in past tense switch for `been` + +0.2.3 / 2012-02-01 +================== + + * try that again + +0.2.2 / 2012-02-01 +================== + + * added `been` (past of `be`) alias + +0.2.1 / 2012-01-29 +================== + + * added Throw, with a capital T, as an alias to `throw` (#7) + +0.2.0 / 2012-01-26 +================== + + * update gitignore for vim *.swp + * Merge branch 'feature/plugins' + * browser build + * interfaces now work with use + * simple .use function. See #9. + * readme notice on browser compat + +0.1.7 / 2012-01-25 +================== + + * added assert tests to browser test runner + * browser update + * `should` interface patch for primitives support in FF + * fix isObject() Thanks @milewise + * travis only on branch `master` + * add instanceof alias `instanceOf`. #6 + * some tests for assert module + +0.1.6 / 2012-01-02 +================== + + * commenting for assert interface + * updated codex dep + +0.1.5 / 2012-01-02 +================== + + * browser tests pass + * type in should.not.equal + * test for should (not) exist + * added should.exist and should.not.exist + * browser uses tdd + * convert tests to tdd + +0.1.4 / 2011-12-26 +================== + + * browser lib update for new assert interface compatiblitiy + * inspect typos + * added strict equal + negatives and ifError + * interface assert had doesNotThrow + * added should tests to browser + * new expect empty tests + * should test browser compat + * Fix typo for instanceof docs. Closes #3 [ci skip] + +0.1.3 / 2011-12-18 +================== + + * much cleaner reporting string on error. + +0.1.2 / 2011-12-18 +================== + + * [docs] for upcoming 0.1.2 + * browser version built with pre/suffix … all tests passing + * make / compile now use prefix/suffix correctly + * code clean + * prefix/suffix to wrap browser output to prevent conflicts with other `require` methods. + * Merge branch 'feature/should4xcompatibility' + * compile for browser tests.. all pass + * added header/status/html/json + * throw tests + * should.throw & should.not.throw shortcuts + * improved `throw` type detection and messaging + * contain is now `include` … keys modifier is now `contain` + * removed object() test + * removed #respondTo + * Merge branch 'bug/2' + * replaced __defineGetter__ with defineProperty for all uses + * [docs] change mp tracking code + * docs site updated with assert (TDD) interface + * updated doc comments for assert interface + +0.1.1 / 2011-12-16 +================== + + * docs ready for upcoming 0.1.1 + * readme image fixed [ci skip] + * more readme tweaks [ci skip] + * réadmet image fixed [ci skip] + * documentation + * codex locked in version 0.0.5 + * more comments to assertions for docs + * assertions fully commented, browser library updated + * adding codex as doc dependancy + * prepping for docs + * assertion component completely commented for documentation + * added exist test + * var expect outside of browser if check + * added keywords to package.json + +0.1.0 / 2011-12-15 +================== + + * failing on purpose successful .. back to normal + * testing travis failure + * assert#arguments getter + * readme typo + * updated README + * added travis and npmignore + * copyright notices … think i got them all + * moved expect interface to own file for consistency + * assert ui deepEqual + * browser tests expect (all working) + * browser version built + * chai.fail (should ui) + * expect tests browser compatible + * tests for should and expect (all pass) + * moved fail to primary export + * should compatibility testing + * within, greaterThan, object, keys, + * Aliases + * Assertion#property now correctly works with negate and undefined values + * error message language matches should + * Assertion#respondTo + * Assertion now uses inspect util + * git ignore node modules + * should is exported + * AssertionError __proto__ from Error.prototype + * add should interface for should.js compatibility + * moved eql to until folder and added inspect from (joyent/node) + * added mocha for testing + * browser build for current api + * multiple .property assertions + * added deep equal from node + +0.0.2 / 2011-12-07 +================== + + * cleaner output on error + * improved exists detection + * package remnant artifact + * empty deep equal + * test browser build + * assertion cleanup + * client compile script + * makefile + * most of the basic assertions + * allow no parameters to assertion error + * name change + * assertion error instance + * main exports: assert() & expect() + * initialize diff --git a/node_modules/chai/LICENSE b/node_modules/chai/LICENSE new file mode 100644 index 000000000..eedbe238a --- /dev/null +++ b/node_modules/chai/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Chai.js Assertion Library + +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/node_modules/chai/README.md b/node_modules/chai/README.md new file mode 100644 index 000000000..5d4bfa702 --- /dev/null +++ b/node_modules/chai/README.md @@ -0,0 +1,212 @@ +

+ + ChaiJS + +
+ chai +

+ +

+ Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework. +

+ +

+ + license:mit + + + tag:? + + + node:? + +
+ + Selenium Test Status + +
+ + downloads:? + + + build:? + + + coverage:? + + + devDependencies:? + +
+ + Join the Slack chat + + + Join the Gitter chat + + + OpenCollective Backers + +

+ +For more information or to download plugins, view the [documentation](http://chaijs.com). + +## What is Chai? + +Chai is an _assertion library_, similar to Node's build in `assert`. It makes testing much easier by giving you lots of assertions you can run against your code. + +## Installation + +### Node.js + +`chai` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install chai + +### Browsers + +You can also use it within the browser; install via npm and use the `chai.js` file found within the download. For example: + +```html + +``` + +## Usage + +Import the library in your code, and then pick one of the styles you'd like to use - either `assert`, `expect` or `should`: + +```js +var chai = require('chai'); +var assert = chai.assert; // Using Assert style +var expect = chai.expect; // Using Expect style +var should = chai.should(); // Using Should style +``` + +### Pre-Native Modules Usage (_registers the chai testing style globally_) + +```js +require('chai/register-assert'); // Using Assert style +require('chai/register-expect'); // Using Expect style +require('chai/register-should'); // Using Should style +``` + +### Pre-Native Modules Usage (_as local variables_) + +```js +const { assert } = require('chai'); // Using Assert style +const { expect } = require('chai'); // Using Expect style +const { should } = require('chai'); // Using Should style +should(); // Modifies `Object.prototype` + +const { expect, use } = require('chai'); // Creates local variables `expect` and `use`; useful for plugin use +``` + +### Native Modules Usage (_registers the chai testing style globally_) + +```js +import 'chai/register-assert'; // Using Assert style +import 'chai/register-expect'; // Using Expect style +import 'chai/register-should'; // Using Should style +``` + +### Native Modules Usage (_local import only_) + +```js +import { assert } from 'chai'; // Using Assert style +import { expect } from 'chai'; // Using Expect style +import { should } from 'chai'; // Using Should style +should(); // Modifies `Object.prototype` +``` + +### Usage with Mocha + +```bash +mocha spec.js -r chai/register-assert # Using Assert style +mocha spec.js -r chai/register-expect # Using Expect style +mocha spec.js -r chai/register-should # Using Should style +``` + +[Read more about these styles in our docs](http://chaijs.com/guide/styles/). + +## Plugins + +Chai offers a robust Plugin architecture for extending Chai's assertions and interfaces. + +- Need a plugin? View the [official plugin list](http://chaijs.com/plugins). +- Want to build a plugin? Read the [plugin api documentation](http://chaijs.com/guide/plugins/). +- Have a plugin and want it listed? Simply add the following keywords to your package.json: + - `chai-plugin` + - `browser` if your plugin works in the browser as well as Node.js + - `browser-only` if your plugin does not work with Node.js + +### Related Projects + +- [chaijs / chai-docs](https://github.com/chaijs/chai-docs): The chaijs.com website source code. +- [chaijs / assertion-error](https://github.com/chaijs/assertion-error): Custom `Error` constructor thrown upon an assertion failing. +- [chaijs / deep-eql](https://github.com/chaijs/deep-eql): Improved deep equality testing for Node.js and the browser. +- [chaijs / type-detect](https://github.com/chaijs/type-detect): Improved typeof detection for Node.js and the browser. +- [chaijs / check-error](https://github.com/chaijs/check-error): Error comparison and information related utility for Node.js and the browser. +- [chaijs / loupe](https://github.com/chaijs/loupe): Inspect utility for Node.js and browsers. +- [chaijs / pathval](https://github.com/chaijs/pathval): Object value retrieval given a string path. +- [chaijs / get-func-name](https://github.com/chaijs/get-func-name): Utility for getting a function's name for node and the browser. + +### Contributing + +Thank you very much for considering to contribute! + +Please make sure you follow our [Code Of Conduct](https://github.com/chaijs/chai/blob/master/CODE_OF_CONDUCT.md) and we also strongly recommend reading our [Contributing Guide](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md). + +Here are a few issues other contributors frequently ran into when opening pull requests: + +- Please do not commit changes to the `chai.js` build. We do it once per release. +- Before pushing your commits, please make sure you [rebase](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md#pull-requests) them. + +### Contributors + +Please see the full +[Contributors Graph](https://github.com/chaijs/chai/graphs/contributors) for our +list of contributors. + +### Core Contributors + +Feel free to reach out to any of the core contributors with your questions or +concerns. We will do our best to respond in a timely manner. + +[![Jake Luer](https://avatars3.githubusercontent.com/u/58988?v=3&s=50)](https://github.com/logicalparadox) +[![Veselin Todorov](https://avatars3.githubusercontent.com/u/330048?v=3&s=50)](https://github.com/vesln) +[![Keith Cirkel](https://avatars3.githubusercontent.com/u/118266?v=3&s=50)](https://github.com/keithamus) +[![Lucas Fernandes da Costa](https://avatars3.githubusercontent.com/u/6868147?v=3&s=50)](https://github.com/lucasfcosta) +[![Grant Snodgrass](https://avatars3.githubusercontent.com/u/17260989?v=3&s=50)](https://github.com/meeber) diff --git a/node_modules/chai/ReleaseNotes.md b/node_modules/chai/ReleaseNotes.md new file mode 100644 index 000000000..2a80d5cec --- /dev/null +++ b/node_modules/chai/ReleaseNotes.md @@ -0,0 +1,737 @@ +# Release Notes + +## Note + +As of 3.0.0, the ReleaseNotes.md file has been deprecated. [Please refer to the release notes available on Github](https://github.com/chaijs/chai/releases). Or +[the release notes on the chaijs.com website](https://chaijs.com/releases). + +--- + +## 2.3.0 / 2015-04-26 + +Added `ownPropertyDescriptor` assertion: + +```js +expect('test').to.have.ownPropertyDescriptor('length'); +expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); +expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); +expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); +expect('test').ownPropertyDescriptor('length').to.have.keys('value'); +``` + +### Community Contributions + +#### Code Features & Fixes + + * [#408](https://github.com/chaijs/chai/pull/408) Add `ownPropertyDescriptor` + assertion. + By [@ljharb](https://github.com/ljharb) + * [#422](https://github.com/chaijs/chai/pull/422) Improve ownPropertyDescriptor + tests. + By [@ljharb](https://github.com/ljharb) + +#### Documentation fixes + + * [#417](https://github.com/chaijs/chai/pull/417) Fix documentation typo + By [@astorije](https://github.com/astorije) + * [#423](https://github.com/chaijs/chai/pull/423) Fix inconsistency in docs. + By [@ehntoo](https://github.com/ehntoo) + + +## 2.2.0 / 2015-03-26 + +Deep property strings can now be escaped using `\\` - for example: + +```js +var deepCss = { '.link': { '[target]': 42 }}; +expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42) +``` + +### Community Contributions + +#### Code Features & Fixes + + * [#402](https://github.com/chaijs/chai/pull/402) Allow escaping of deep + property keys. + By [@umireon](https://github.com/umireon) + +#### Documentation fixes + + * [#405](https://github.com/chaijs/chai/pull/405) Tweak documentation around + deep property escaping. + By [@keithamus](https://github.com/keithamus) + + +## 2.1.2 / 2015-03-15 + +A minor bug fix. No new features. + +### Community Contributions + +#### Code Features & Fixes + + * [#395](https://github.com/chaijs/chai/pull/395) Fix eval-related bugs with + assert.operator ([#386](https://github.com/chaijs/chai/pull/386)). + By [@cjqed](https://github.com/cjqed) + +## 2.1.1 / 2015-03-04 + +Two minor bugfixes. No new features. + +### Community Contributions + +#### Code Features & Fixes + + * [#385](https://github.com/chaijs/chai/pull/385) Fix a bug (also described in + [#387](https://github.com/chaijs/chai/pull/385)) where `deep.property` would not work with single + key names. By [@eldritch-fossicker](https://github.com/eldritch-fossicker) + * [#379](https://github.com/chaijs/chai/pull/379) Fix bug where tools which overwrite + primitive prototypes, such as Babel or core-js would fail. + By [@dcneiner](https://github.com/dcneiner) + +#### Documentation fixes + + * [#382](https://github.com/chaijs/chai/pull/382) Add doc for showDiff argument in assert. + By [@astorije](https://github.com/astorije) + * [#383](https://github.com/chaijs/chai/pull/383) Improve wording for truncateTreshold docs + By [@gurdiga](https://github.com/gurdiga) + * [#381](https://github.com/chaijs/chai/pull/381) Improve wording for assert.empty docs + By [@astorije](https://github.com/astorije) + +## 2.1.0 / 2015-02-23 + +Small release; fixes an issue where the Chai lib was incorrectly reporting the +version number. + +Adds new `should.fail()` and `expect.fail()` methods, which are convinience +methods to throw Assertion Errors. + +### Community Contributions + +#### Code Features & Fixes + + * [#356](https://github.com/chaijs/chai/pull/356) Add should.fail(), expect.fail(). By [@Soviut](https://github.com/Soviut) + * [#374](https://github.com/chaijs/chai/pull/374) Increment version. By [@jmm](https://github.com/jmm) + +## 2.0.0 / 2015-02-09 + +Unfortunately with 1.10.0 - compatibility broke with older versions because of +the `addChainableNoop`. This change has been reverted. + +Any plugins using `addChainableNoop` should cease to do so. + +Any developers wishing for this behaviour can use [dirty-chai](https://www.npmjs.com/package/dirty-chai) +by [@joshperry](https://github.com/joshperry) + +### Community Contributions + +#### Code Features & Fixes + + * [#361](https://github.com/chaijs/chai/pull/361) `.keys()` now accepts Objects, extracting keys from them. By [@gregglind](https://github.com/gregglind) + * [#359](https://github.com/chaijs/chai/pull/359) `.keys()` no longer mutates passed arrays. By [@gregglind](https://github.com/gregglind) + * [#349](https://github.com/chaijs/chai/pull/349) Add a new chainable keyword - `.which`. By [@toastynerd](https://github.com/toastynerd) + * [#333](https://github.com/chaijs/chai/pull/333) Add `.change`, `.increase` and `.decrease` assertions. By [@cmpolis](https://github.com/cmpolis) + * [#335](https://github.com/chaijs/chai/pull/335) `chai.util` is now exposed [@DingoEatingFuzz](https://github.com/DingoEatingFuzz) + * [#328](https://github.com/chaijs/chai/pull/328) Add `.includes` and `.contains` aliases (for `.include` and `.contain`). By [@lo1tuma](https://github.com/lo1tuma) + * [#313](https://github.com/chaijs/chai/pull/313) Add `.any.keys()` and `.all.keys()` qualifiers. By [@cjqed](https://github.com/cjqed) + * [#312](https://github.com/chaijs/chai/pull/312) Add `assert.sameDeepMembers()`. By [@cjqed](https://github.com/cjqed) + * [#311](https://github.com/chaijs/chai/pull/311) Add `assert.isAbove()` and `assert.isBelow()`. By [@cjqed](https://github.com/cjqed) + * [#308](https://github.com/chaijs/chai/pull/308) `property` and `deep.property` now pass if a value is set to `undefined`. By [@prodatakey](https://github.com/prodatakey) + * [#309](https://github.com/chaijs/chai/pull/309) optimize deep equal in Arrays. By [@ericdouglas](https://github.com/ericdouglas) + * [#306](https://github.com/chaijs/chai/pull/306) revert #297 - allowing lint-friendly tests. By [@keithamus](https://github.com/keithamus) + +#### Documentation fixes + + * [#357](https://github.com/chaijs/chai/pull/357) Copyright year updated in docs. By [@danilovaz](https://github.com/danilovaz) + * [#325](https://github.com/chaijs/chai/pull/325) Fix documentation for overwriteChainableMethod. By [@chasenlehara](https://github.com/chasenlehara) + * [#334](https://github.com/chaijs/chai/pull/334) Typo fix. By [@hurrymaplelad](https://github.com/hurrymaplelad) + * [#317](https://github.com/chaijs/chai/pull/317) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + * [#318](https://github.com/chaijs/chai/pull/318) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + * [#316](https://github.com/chaijs/chai/pull/316) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + + +## 1.10.0 / 2014-11-10 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - Review `addChainableNoop` notes below. +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Noop Function for Terminating Assertion Properties + +The following assertions can now also be used in the function-call form: + +* ok +* true +* false +* null +* undefined +* exist +* empty +* arguments +* Arguments + +The above list of assertions are property getters that assert immediately on +access. Because of that, they were written to be used by terminating the assertion +chain with a property access. + +```js +expect(true).to.be.true; +foo.should.be.ok; +``` + +This syntax is definitely aesthetically pleasing but, if you are linting your +test code, your linter will complain with an error something like "Expected an +assignment or function call and instead saw an expression." Since the linter +doesn't know about the property getter it assumes this line has no side-effects, +and throws a warning in case you made a mistake. + +Squelching these errors is not a good solution as test code is getting to be +just as important as, if not more than, production code. Catching syntactical +errors in tests using static analysis is a great tool to help make sure that your +tests are well-defined and free of typos. + +A better option was to provide a function-call form for these assertions so that +the code's intent is more clear and the linters stop complaining about something +looking off. This form is added in addition to the existing property access form +and does not impact existing test code. + +```js +expect(true).to.be.true(); +foo.should.be.ok(); +``` + +These forms can also be mixed in any way, these are all functionally identical: + +```js +expect(true).to.be.true.and.not.false(); +expect(true).to.be.true().and.not.false; +expect(true).to.be.true.and.not.false; +``` + +#### Plugin Authors + +If you would like to provide this function-call form for your terminating assertion +properties, there is a new function to register these types of asserts. Instead +of using `addProperty` to register terminating assertions, simply use `addChainableNoop` +instead; the arguments to both are identical. The latter will make the assertion +available in both the attribute and function-call forms and should have no impact +on existing users of your plugin. + +### Community Contributions + +- [#297](https://github.com/chaijs/chai/pull/297) Allow writing lint-friendly tests. [@joshperry](https://github.com/joshperry) +- [#298](https://github.com/chaijs/chai/pull/298) Add check for logging `-0`. [@dasilvacontin](https://github.com/dasilvacontin) +- [#300](https://github.com/chaijs/chai/pull/300) Fix #299: the test is defining global variables [@julienw](https://github.com/julienw) + +Thank you to all who took time to contribute! + +## 1.9.2 / 2014-09-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Community Contributions + +- [#264](https://github.com/chaijs/chai/pull/264) Show diff for keys assertions [@cjthompson](https://github.com/cjthompson) +- [#267](https://github.com/chaijs/chai/pull/267) Use SVG badges [@shinnn](https://github.com/shinnn) +- [#268](https://github.com/chaijs/chai/pull/268) Allow messages to be functions (sinon-compat) [@charlierudolph](https://github.com/charlierudolph) +- [#269](https://github.com/chaijs/chai/pull/269) Remove unused argument for #lengthOf [@charlierudolph](https://github.com/charlierudolph) +- [#275](https://github.com/chaijs/chai/pull/275) Rewrite pretty-printing HTML elements to prevent throwing internal errors [@DrRataplan](https://github.com/DrRataplan) +- [#277](https://github.com/chaijs/chai/pull/277) Fix assert documentation for #sameMembers [@charlierudolph](https://github.com/charlierudolph) +- [#279](https://github.com/chaijs/chai/pull/279) closeTo should check value's type before assertion [@mohayonao](https://github.com/mohayonao) +- [#289](https://github.com/chaijs/chai/pull/289) satisfy is called twice [@charlierudolph](https://github.com/charlierudolph) +- [#292](https://github.com/chaijs/chai/pull/292) resolve conflicts with node-webkit and global usage [@boneskull](https://github.com/boneskull) + +Thank you to all who took time to contribute! + +## 1.9.1 / 2014-03-19 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - Migrate configuration options to new interface. (see notes) +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Configuration + +There have been requests for changes and additions to the configuration mechanisms +and their impact in the Chai architecture. As such, we have decoupled the +configuration from the `Assertion` constructor. This not only allows for centralized +configuration, but will allow us to shift the responsibility from the `Assertion` +constructor to the `assert` interface in future releases. + +These changes have been implemented in a non-breaking way, but a depretiation +warning will be presented to users until they migrate. The old config method will +be removed in either `v1.11.0` or `v2.0.0`, whichever comes first. + +#### Quick Migration + +```js +// change this: +chai.Assertion.includeStack = true; +chai.Assertion.showDiff = false; + +// ... to this: +chai.config.includeStack = true; +chai.config.showDiff = false; +``` + +#### All Config Options + +##### config.includeStack + +- **@param** _{Boolean}_ +- **@default** `false` + +User configurable property, influences whether stack trace is included in +Assertion error message. Default of `false` suppresses stack trace in the error +message. + +##### config.showDiff + +- **@param** _{Boolean}_ +- **@default** `true` + +User configurable property, influences whether or not the `showDiff` flag +should be included in the thrown AssertionErrors. `false` will always be `false`; +`true` will be true when the assertion has requested a diff be shown. + +##### config.truncateThreshold **(NEW)** + +- **@param** _{Number}_ +- **@default** `40` + +User configurable property, sets length threshold for actual and expected values +in assertion errors. If this threshold is exceeded, the value is truncated. + +Set it to zero if you want to disable truncating altogether. + +```js +chai.config.truncateThreshold = 0; // disable truncating +``` + +### Community Contributions + +- [#228](https://github.com/chaijs/chai/pull/228) Deep equality check for memebers. [@duncanbeevers](https://github.com/duncanbeevers) +- [#247](https://github.com/chaijs/chai/pull/247) Proofreading. [@didorellano](https://github.com/didoarellano) +- [#244](https://github.com/chaijs/chai/pull/244) Fix `contain`/`include` 1.9.0 regression. [@leider](https://github.com/leider) +- [#233](https://github.com/chaijs/chai/pull/233) Improvements to `ssfi` for `assert` interface. [@refack](https://github.com/refack) +- [#251](https://github.com/chaijs/chai/pull/251) New config option: object display threshold. [@romario333](https://github.com/romario333) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#183](https://github.com/chaijs/chai/issues/183) Allow `undefined` for actual. (internal api) +- Update Karam(+plugins)/Istanbul to most recent versions. + +## 1.9.0 / 2014-01-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - Review [#219](https://github.com/chaijs/chai/pull/219). +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Community Contributions + +- [#202](https://github.com/chaijs/chai/pull/201) Improve error message for .throw(). [@andreineculau](https://github.com/andreineculau) +- [#217](https://github.com/chaijs/chai/pull/217) Chai tests can be run with `--watch`. [@demands](https://github.com/demands) +- [#219](https://github.com/chaijs/chai/pull/219) Add overwriteChainableMethod utility. [@demands](https://github.com/demands) +- [#224](https://github.com/chaijs/chai/pull/224) Return error on throw method to chain on error properties. [@vbardales](https://github.com/vbardales) +- [#226](https://github.com/chaijs/chai/pull/226) Add `has` to language chains. [@duncanbeevers](https://github.com/duncanbeevers) +- [#230](https://github.com/chaijs/chai/pull/230) Support `{a:1,b:2}.should.include({a:1})` [@jkroso](https://github.com/jkroso) +- [#231](https://github.com/chaijs/chai/pull/231) Update Copyright notices to 2014 [@duncanbeevers](https://github.com/duncanbeevers) +- [#232](https://github.com/chaijs/chai/pull/232) Avoid error instantiation if possible on assert.throws. [@laconbass](https://github.com/laconbass) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#225](https://github.com/chaijs/chai/pull/225) Improved AMD wrapper provided by upstream `component(1)`. +- [#185](https://github.com/chaijs/chai/issues/185) `assert.throws()` returns thrown error for further assertions. +- [#237](https://github.com/chaijs/chai/pull/237) Remove coveralls/jscoverage, include istanbul coverage report in travis test. +- Update Karma and Sauce runner versions for consistent CI results. No more karma@canary. + +## 1.8.1 / 2013-10-10 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - Refresh `node_modules` folder for updated dependencies. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Browserify + +This is a small patch that updates the dependency tree so browserify users can install +chai. (Remove conditional requires) + +## 1.8.0 / 2013-09-18 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - See `deep.equal` notes. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Deep Equals + +This version of Chai focused on a overhaul to the deep equal utility. The code for this +tool has been removed from the core lib and can now be found at: +[chai / deep-eql](https://github.com/chaijs/deep-eql). As stated in previous releases, +this is part of a larger initiative to provide transparency, independent testing, and coverage for +some of the more complicated internal tools. + +For the most part `.deep.equal` will behave the same as it has. However, in order to provide a +consistent ruleset across all types being tested, the following changes have been made and _might_ +require changes to your tests. + +**1.** Strict equality for non-traversable nodes according to [egal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + +_Previously:_ Non-traversable equal via `===`. + +```js +expect(NaN).to.deep.equal(NaN); +expect(-0).to.not.deep.equal(+0); +``` + +**2.** Arguments are not Arrays (and all types must be equal): + +_Previously:_ Some crazy nonsense that led to empty arrays deep equaling empty objects deep equaling dates. + +```js +expect(arguments).to.not.deep.equal([]); +expect(Array.prototype.slice.call(arguments)).to.deep.equal([]); +``` + +- [#156](https://github.com/chaijs/chai/issues/156) Empty object is eql to empty array +- [#192](https://github.com/chaijs/chai/issues/192) empty object is eql to a Date object +- [#194](https://github.com/chaijs/chai/issues/194) refactor deep-equal utility + +### CI and Browser Testing + +Chai now runs the browser CI suite using [Karma](http://karma-runner.github.io/) directed at +[SauceLabs](https://saucelabs.com/). This means we get to know where our browser support stands... +and we get a cool badge: + +[![Selenium Test Status](https://saucelabs.com/browser-matrix/logicalparadox.svg)](https://saucelabs.com/u/logicalparadox) + +Look for the list of browsers/versions to expand over the coming releases. + +- [#195](https://github.com/chaijs/chai/issues/195) karma test framework + +## 1.7.2 / 2013-06-27 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Coverage Reporting + +Coverage reporting has always been available for core-developers but the data has never been published +for our end users. In our ongoing effort to improve accountability this data will now be published via +the [coveralls.io](https://coveralls.io/) service. A badge has been added to the README and the full report +can be viewed online at the [chai coveralls project](https://coveralls.io/r/chaijs/chai). Furthermore, PRs +will receive automated messages indicating how their PR impacts test coverage. This service is tied to TravisCI. + +### Other Fixes + +- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. (Fix ignore all) + +## 1.7.1 / 2013-06-24 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Official Bower Support + +Support has been added for the Bower Package Manager ([bower.io])(http://bower.io/). Though +Chai could be installed via Bower in the past, this update adds official support via the `bower.json` +specification file. + +- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. + +## 1.7.0 / 2013-06-17 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - Review AssertionError update notice. +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### AssertionError Update Notice + +Chai now uses [chaijs/assertion-error](https://github.com/chaijs/assertion-error) instead an internal +constructor. This will allow for further iteration/experimentation of the AssertionError constructor +independant of Chai. Future plans include stack parsing for callsite support. + +This update constructor has a different constructor param signature that conforms more with the standard +`Error` object. If your plugin throws and `AssertionError` directly you will need to update your plugin +with the new signature. + +```js +var AssertionError = require('chai').AssertionError; + +/** + * previous + * + * @param {Object} options + */ + +throw new AssertionError({ + message: 'An assertion error occurred' + , actual: actual + , expect: expect + , startStackFunction: arguments.callee + , showStack: true +}); + +/** + * new + * + * @param {String} message + * @param {Object} options + * @param {Function} start stack function + */ + +throw new AssertionError('An assertion error occurred', { + actual: actual + , expect: expect + , showStack: true +}, arguments.callee); + +// other signatures +throw new AssertionError('An assertion error occurred'); +throw new AssertionError('An assertion error occurred', null, arguments.callee); +``` + +#### External Dependencies + +This is the first non-developement dependency for Chai. As Chai continues to evolve we will begin adding +more; the next will likely be improved type detection and deep equality. With Chai's userbase continually growing +there is an higher need for accountability and documentation. External dependencies will allow us to iterate and +test on features independent from our interfaces. + +Note: The browser packaged version `chai.js` will ALWAYS contain all dependencies needed to run Chai. + +### Community Contributions + +- [#169](https://github.com/chaijs/chai/pull/169) Fix deep equal comparison for Date/Regexp types. [@katsgeorgeek](https://github.com/katsgeorgeek) +- [#171](https://github.com/chaijs/chai/pull/171) Add `assert.notOk()`. [@Bartvds](https://github.com/Bartvds) +- [#173](https://github.com/chaijs/chai/pull/173) Fix `inspect` utility. [@domenic](https://github.com/domenic) + +Thank you to all who took the time to contribute! + +## 1.6.1 / 2013-06-05 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### Deep Equality + +Regular Expressions are now tested as part of all deep equality assertions. In previous versions +they silently passed for all scenarios. Thanks to [@katsgeorgeek](https://github.com/katsgeorgeek) for the contribution. + +### Community Contributions + +- [#161](https://github.com/chaijs/chai/pull/161) Fix documented name for assert interface's isDefined method. [@brandonpayton](https://github.com/brandonpayton) +- [#168](https://github.com/chaijs/chai/pull/168) Fix comparison equality of two regexps for when using deep equality. [@katsgeorgeek](https://github.com/katsgeorgeek) + +Thank you to all who took the time to contribute! + +### Additional Notes + +- Mocha has been locked at version `1.8.x` to ensure `mocha-phantomjs` compatibility. + +## 1.6.0 / 2013-04-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### New Assertions + +#### Array Members Inclusion + +Asserts that the target is a superset of `set`, or that the target and `set` have the same members. +Order is not taken into account. Thanks to [@NickHeiner](https://github.com/NickHeiner) for the contribution. + +```js +// (expect/should) full set +expect([4, 2]).to.have.members([2, 4]); +expect([5, 2]).to.not.have.members([5, 2, 1]); + +// (expect/should) inclusion +expect([1, 2, 3]).to.include.members([3, 2]); +expect([1, 2, 3]).to.not.include.members([3, 2, 8]); + +// (assert) full set +assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + +// (assert) inclusion +assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); + +``` + +#### Non-inclusion for Assert Interface + +Most `assert` functions have a negative version, like `instanceOf()` has a corresponding `notInstaceOf()`. +However `include()` did not have a corresponding `notInclude()`. This has been added. + +```js +assert.notInclude([ 1, 2, 3 ], 8); +assert.notInclude('foobar', 'baz'); +``` + +### Community Contributions + +- [#140](https://github.com/chaijs/chai/pull/140) Restore `call`/`apply` methods for plugin interface. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#148](https://github.com/chaijs/chai/issues/148)/[#153](https://github.com/chaijs/chai/pull/153) Add `members` and `include.members` assertions. [#NickHeiner](https://github.com/NickHeiner) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#142](https://github.com/chaijs/chai/issues/142) `assert#include` will no longer silently pass on wrong-type haystack. +- [#158](https://github.com/chaijs/chai/issues/158) `assert#notInclude` has been added. +- Travis-CI now tests Node.js `v0.10.x`. Support for `v0.6.x` has been removed. `v0.8.x` is still tested as before. + +## 1.5.0 / 2013-02-03 + +### Migration Requirements + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - _Update [2013-02-04]:_ Some users may notice a small subset of deep equality assertions will no longer pass. This is the result of + [#120](https://github.com/chaijs/chai/issues/120), an improvement to our deep equality algorithm. Users will need to revise their assertions + to be more granular should this occur. Further information: [#139](https://github.com/chaijs/chai/issues/139). +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### Community Contributions + +- [#126](https://github.com/chaijs/chai/pull/126): Add `eqls` alias for `eql`. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#127](https://github.com/chaijs/chai/issues/127): Performance refactor for chainable methods. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#133](https://github.com/chaijs/chai/pull/133): Assertion `.throw` support for primitives. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#137](https://github.com/chaijs/chai/issues/137): Assertion `.throw` support for empty messages. [@timnew](https://github.com/timnew) +- [#136](https://github.com/chaijs/chai/pull/136): Fix backward negation messages when using `.above()` and `.below()`. [@whatthejeff](https://github.com/whatthejeff) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- Improve type detection of `.a()`/`.an()` to work in cross-browser scenarios. +- [#116](https://github.com/chaijs/chai/issues/116): `.throw()` has cleaner display of errors when WebKit browsers. +- [#120](https://github.com/chaijs/chai/issues/120): `.eql()` now works to compare dom nodes in browsers. + + +### Usage Updates + +#### For Users + +**1. Component Support:** Chai now included the proper configuration to be installed as a +[component](https://github.com/component/component). Component users are encouraged to consult +[chaijs.com](http://chaijs.com) for the latest version number as using the master branch +does not gaurantee stability. + +```js +// relevant component.json + devDependencies: { + "chaijs/chai": "1.5.0" + } +``` + +Alternatively, bleeding-edge is available: + + $ component install chaijs/chai + +**2. Configurable showDiff:** Some test runners (such as [mocha](http://visionmedia.github.com/mocha/)) +include support for showing the diff of strings and objects when an equality error occurs. Chai has +already included support for this, however some users may not prefer this display behavior. To revert to +no diff display, the following configuration is available: + +```js +chai.Assertion.showDiff = false; // diff output disabled +chai.Assertion.showDiff = true; // default, diff output enabled +``` + +#### For Plugin Developers + +**1. New Utility - type**: The new utility `.type()` is available as a better implementation of `typeof` +that can be used cross-browser. It handles the inconsistencies of Array, `null`, and `undefined` detection. + +- **@param** _{Mixed}_ object to detect type of +- **@return** _{String}_ object type + +```js +chai.use(function (c, utils) { + // some examples + utils.type({}); // 'object' + utils.type(null); // `null' + utils.type(undefined); // `undefined` + utils.type([]); // `array` +}); +``` + +#### For Core Contributors + +**1. Browser Testing**: Browser testing of the `./chai.js` file is now available in the command line +via PhantomJS. `make test` and Travis-CI will now also rebuild and test `./chai.js`. Consequently, all +pull requests will now be browser tested in this way. + +_Note: Contributors opening pull requests should still NOT include the browser build._ + +**2. SauceLabs Testing**: Early SauceLab support has been enabled with the file `./support/mocha-cloud.js`. +Those interested in trying it out should create a free [Open Sauce](https://saucelabs.com/signup/plan) account +and include their credentials in `./test/auth/sauce.json`. diff --git a/node_modules/chai/chai.js b/node_modules/chai/chai.js new file mode 100644 index 000000000..3aea7626b --- /dev/null +++ b/node_modules/chai/chai.js @@ -0,0 +1,10707 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o + * MIT Licensed + */ + +var used = []; + +/*! + * Chai version + */ + +exports.version = '4.1.2'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai. + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(exports, util); + used.push(fn); + } + + return exports; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); + +},{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":33}],3:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * @param {Mixed} obj target of the assertion + * @param {String} msg (optional) custom error message + * @param {Function} ssfi (optional) starting point for removing stack frames + * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked + * @api private + */ + + function Assertion (obj, msg, ssfi, lockSsfi) { + flag(this, 'ssfi', ssfi || Assertion); + flag(this, 'lockSsfi', lockSsfi); + flag(this, 'object', obj); + flag(this, 'message', msg); + + return util.proxify(this); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (false !== showDiff) showDiff = true; + if (undefined === expected && undefined === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + msg = util.getMessage(this, arguments); + var actual = util.getActual(this, arguments); + throw new AssertionError(msg, { + actual: actual + , expected: expected + , showDiff: showDiff + }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; + +},{"./config":4}],4:[function(require,module,exports){ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40, + + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {Boolean} + * @api public + */ + + useProxy: true, + + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @api public + */ + + proxyExcludedKeys: ['then', 'inspect', 'toJSON'] +}; + +},{}],5:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , AssertionError = chai.AssertionError + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to improve the readability + * of your assertions. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * - but + * - does + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been' + , 'is', 'and', 'has', 'have' + , 'with', 'that', 'which', 'at' + , 'of', 'same', 'but', 'does' ].forEach(function (chain) { + Assertion.addProperty(chain); + }); + + /** + * ### .not + * + * Negates all assertions that follow in the chain. + * + * expect(function () {}).to.not.throw(); + * expect({a: 1}).to.not.have.property('b'); + * expect([1, 2]).to.be.an('array').that.does.not.include(3); + * + * Just because you can negate any assertion with `.not` doesn't mean you + * should. With great power comes great responsibility. It's often best to + * assert that the one expected output was produced, rather than asserting + * that one of countless unexpected outputs wasn't produced. See individual + * assertions for specific guidance. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.equal(1); // Not recommended + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` + * assertions that follow in the chain to use deep equality instead of strict + * (`===`) equality. See the `deep-eql` project page for info on the deep + * equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .nested + * + * Enables dot- and bracket-notation in all `.property` and `.include` + * assertions that follow in the chain. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); + * + * `.nested` cannot be combined with `.own`. + * + * @name nested + * @namespace BDD + * @api public + */ + + Assertion.addProperty('nested', function () { + flag(this, 'nested', true); + }); + + /** + * ### .own + * + * Causes all `.property` and `.include` assertions that follow in the chain + * to ignore inherited properties. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.property('b').but.not.own.property('b'); + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * `.own` cannot be combined with `.nested`. + * + * @name own + * @namespace BDD + * @api public + */ + + Assertion.addProperty('own', function () { + flag(this, 'own', true); + }); + + /** + * ### .ordered + * + * Causes all `.members` assertions that follow in the chain to require that + * members be in the same order. + * + * expect([1, 2]).to.have.ordered.members([1, 2]) + * .but.not.have.ordered.members([2, 1]); + * + * When `.include` and `.ordered` are combined, the ordering begins at the + * start of both arrays. + * + * expect([1, 2, 3]).to.include.ordered.members([1, 2]) + * .but.not.include.ordered.members([2, 3]); + * + * @name ordered + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ordered', function () { + flag(this, 'ordered', true); + }); + + /** + * ### .any + * + * Causes all `.keys` assertions that follow in the chain to only require that + * the target have at least one of the given keys. This is the opposite of + * `.all`, which requires that the target have all of the given keys. + * + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false); + }); + + + /** + * ### .all + * + * Causes all `.keys` assertions that follow in the chain to require that the + * target have all of the given keys. This is the opposite of `.any`, which + * only requires that the target have at least one of the given keys. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` are + * added earlier in the chain. However, it's often best to add `.all` anyway + * because it improves readability. + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type[, msg]) + * + * Asserts that the target's type is equal to the given string `type`. Types + * are case insensitive. See the `type-detect` project page for info on the + * type detection algorithm: https://github.com/chaijs/type-detect. + * + * expect('foo').to.be.a('string'); + * expect({a: 1}).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(Promise.resolve()).to.be.a('promise'); + * expect(new Float32Array).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. + * + * var myObj = { + * [Symbol.toStringTag]: 'myCustomType' + * }; + * + * expect(myObj).to.be.a('myCustomType').but.not.an('object'); + * + * It's often best to use `.a` to check a target's type before making more + * assertions on the same target. That way, you avoid unexpected behavior from + * any assertion that does different things based on the target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.a`. However, it's often best to + * assert that the target is the expected type, rather than asserting that it + * isn't one of many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.an('array'); // Not recommended + * + * `.a` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * expect(1).to.be.a('string', 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.a('string'); + * + * `.a` can also be used as a language chain to improve the readability of + * your assertions. + * + * expect({b: 2}).to.have.a.property('b'); + * + * The alias `.an` can be used interchangeably with `.a`. + * + * @name a + * @alias an + * @param {String} type + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj).toLowerCase() + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(val[, msg]) + * + * When the target is a string, `.include` asserts that the given string `val` + * is a substring of the target. + * + * expect('foobar').to.include('foo'); + * + * When the target is an array, `.include` asserts that the given `val` is a + * member of the target. + * + * expect([1, 2, 3]).to.include(2); + * + * When the target is an object, `.include` asserts that the given object + * `val`'s properties are a subset of the target's properties. + * + * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); + * + * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a + * member of the target. SameValueZero equality algorithm is used. + * + * expect(new Set([1, 2])).to.include(2); + * + * When the target is a Map, `.include` asserts that the given `val` is one of + * the values of the target. SameValueZero equality algorithm is used. + * + * expect(new Map([['a', 1], ['b', 2]])).to.include(2); + * + * Because `.include` does different things based on the target's type, it's + * important to check the target's type before using `.include`. See the `.a` + * doc for info on testing a target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * + * By default, strict (`===`) equality is used to compare array members and + * object properties. Add `.deep` earlier in the chain to use deep equality + * instead (WeakSet targets are not supported). See the `deep-eql` project + * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * By default, all of the target's properties are searched when working with + * objects. This includes properties that are inherited and/or non-enumerable. + * Add `.own` earlier in the chain to exclude the target's inherited + * properties from the search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * Note that a target object is always only searched for `val`'s own + * enumerable properties. + * + * `.deep` and `.own` can be combined. + * + * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.include`. + * + * expect('foobar').to.not.include('taco'); + * expect([1, 2, 3]).to.not.include(4); + * + * However, it's dangerous to negate `.include` when the target is an object. + * The problem is that it creates uncertain expectations by asserting that the + * target object doesn't have all of `val`'s key/value pairs but may or may + * not have some of them. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target object isn't even expected to have `val`'s keys, it's + * often best to assert exactly that. + * + * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended + * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended + * + * When the target object is expected to have `val`'s keys, it's often best to + * assert that each of the properties has its expected value, rather than + * asserting that each property doesn't have one of many unexpected values. + * + * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended + * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended + * + * `.include` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.include(4); + * + * `.include` can also be used as a language chain, causing all `.members` and + * `.keys` assertions that follow in the chain to require the target to be a + * superset of the expected set, rather than an identical set. Note that + * `.members` ignores duplicates in the subset when `.include` is added. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * Note that adding `.any` earlier in the chain causes the `.keys` assertion + * to ignore `.include`. + * + * // Both assertions are identical + * expect({a: 1}).to.include.any.keys('a', 'b'); + * expect({a: 1}).to.have.any.keys('a', 'b'); + * + * The aliases `.includes`, `.contain`, and `.contains` can be used + * interchangeably with `.include`. + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function SameValueZero(a, b) { + return (_.isNaN(a) && _.isNaN(b)) || a === b; + } + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + if (msg) flag(this, 'message', msg); + + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , descriptor = isDeep ? 'deep ' : ''; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + var included = false; + + switch (objType) { + case 'string': + included = obj.indexOf(val) !== -1; + break; + + case 'weakset': + if (isDeep) { + throw new AssertionError( + flagMsg + 'unable to use .deep.include with WeakSet', + undefined, + ssfi + ); + } + + included = obj.has(val); + break; + + case 'map': + var isEql = isDeep ? _.eql : SameValueZero; + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + break; + + case 'set': + if (isDeep) { + obj.forEach(function (item) { + included = included || _.eql(item, val); + }); + } else { + included = obj.has(val); + } + break; + + case 'array': + if (isDeep) { + included = obj.some(function (item) { + return _.eql(item, val); + }) + } else { + included = obj.indexOf(val) !== -1; + } + break; + + default: + // This block is for asserting a subset of properties in an object. + // `_.expectTypes` isn't used here because `.include` should work with + // objects with a custom `@@toStringTag`. + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + 'object tested must be an array, a map, an object,' + + ' a set, a string, or a weakset, but ' + objType + ' given', + undefined, + ssfi + ); + } + + var props = Object.keys(val) + , firstErr = null + , numErrs = 0; + + props.forEach(function (prop) { + var propAssertion = new Assertion(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, 'lockSsfi', true); + + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + + // When validating .not.include with multiple properties, we only want + // to throw an assertion error if all of the properties are included, + // in which case we throw the first property assertion error that we + // encountered. + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + + // Assert inclusion in collection or substring in a string. + this.assert( + included + , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val) + , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is loosely (`==`) equal to `true`. However, it's + * often best to assert that the target is strictly (`===`) or deeply equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.ok; // Not recommended + * + * expect(true).to.be.true; // Recommended + * expect(true).to.be.ok; // Not recommended + * + * Add `.not` earlier in the chain to negate `.ok`. + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.not.be.ok; // Not recommended + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.ok; // Not recommended + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.be.ok; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.be.ok; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is strictly (`===`) equal to `true`. + * + * expect(true).to.be.true; + * + * Add `.not` earlier in the chain to negate `.true`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `true`. + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.true; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.true; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , flag(this, 'negate') ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is strictly (`===`) equal to `false`. + * + * expect(false).to.be.false; + * + * Add `.not` earlier in the chain to negate `.false`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `false`. + * + * expect(true).to.be.true; // Recommended + * expect(true).to.not.be.false; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.false; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(true, 'nooo why fail??').to.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , flag(this, 'negate') ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is strictly (`===`) equal to `null`. + * + * expect(null).to.be.null; + * + * Add `.not` earlier in the chain to negate `.null`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `null`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.null; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is strictly (`===`) equal to `undefined`. + * + * expect(undefined).to.be.undefined; + * + * Add `.not` earlier in the chain to negate `.undefined`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `undefined`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.undefined; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * + * Asserts that the target is exactly `NaN`. + * + * expect(NaN).to.be.NaN; + * + * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `NaN`. + * + * expect('foo').to.equal('foo'); // Recommended + * expect('foo').to.not.be.NaN; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + _.isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is not strictly (`===`) equal to either `null` or + * `undefined`. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.exist; // Not recommended + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.exist; // Not recommended + * + * Add `.not` earlier in the chain to negate `.exist`. + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.exist; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.exist; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(null, 'nooo why fail??').to.exist; + * + * @name exist + * @namespace BDD + * @api public + */ + + Assertion.addProperty('exist', function () { + var val = flag(this, 'object'); + this.assert( + val !== null && val !== undefined + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + }); + + /** + * ### .empty + * + * When the target is a string or array, `.empty` asserts that the target's + * `length` property is strictly (`===`) equal to `0`. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * + * When the target is a map or set, `.empty` asserts that the target's `size` + * property is strictly equal to `0`. + * + * expect(new Set()).to.be.empty; + * expect(new Map()).to.be.empty; + * + * When the target is a non-function object, `.empty` asserts that the target + * doesn't have any own enumerable properties. Properties with Symbol-based + * keys are excluded from the count. + * + * expect({}).to.be.empty; + * + * Because `.empty` does different things based on the target's type, it's + * important to check the target's type before using `.empty`. See the `.a` + * doc for info on testing a target's type. + * + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.empty`. However, it's often + * best to assert that the target contains its expected number of values, + * rather than asserting that it's not empty. + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.not.be.empty; // Not recommended + * + * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended + * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended + * + * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended + * expect({a: 1}).to.not.be.empty; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect([1, 2, 3], 'nooo why fail??').to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var val = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , itemsCount; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + switch (_.type(val).toLowerCase()) { + case 'array': + case 'string': + itemsCount = val.length; + break; + case 'map': + case 'set': + itemsCount = val.size; + break; + case 'weakmap': + case 'weakset': + throw new AssertionError( + flagMsg + '.empty was passed a weak collection', + undefined, + ssfi + ); + case 'function': + var msg = flagMsg + '.empty was passed a function ' + _.getName(val); + throw new AssertionError(msg.trim(), undefined, ssfi); + default: + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), + undefined, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + + this.assert( + 0 === itemsCount + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an `arguments` object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * test(); + * + * Add `.not` earlier in the chain to negate `.arguments`. However, it's often + * best to assert which type the target is expected to be, rather than + * asserting that its not an `arguments` object. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.arguments; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({}, 'nooo why fail??').to.be.arguments; + * + * The alias `.Arguments` can be used interchangeably with `.arguments`. + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = _.type(obj); + this.assert( + 'Arguments' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(val[, msg]) + * + * Asserts that the target is strictly (`===`) equal to the given `val`. + * + * expect(1).to.equal(1); + * expect('foo').to.equal('foo'); + * + * Add `.deep` earlier in the chain to use deep equality instead. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) equals `[1, 2]` + * expect([1, 2]).to.deep.equal([1, 2]); + * expect([1, 2]).to.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.equal`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to one of countless unexpected values. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.equal(2); // Not recommended + * + * `.equal` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.equal(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.equal(2); + * + * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. + * + * @name equal + * @alias equals + * @alias eq + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + return this.eql(val); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(obj[, msg]) + * + * Asserts that the target is deeply equal to the given `obj`. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object is deeply (but not strictly) equal to {a: 1} + * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); + * + * // Target array is deeply (but not strictly) equal to [1, 2] + * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.eql`. However, it's often best + * to assert that the target is deeply equal to its expected value, rather + * than not deeply equal to one of countless unexpected values. + * + * expect({a: 1}).to.eql({a: 1}); // Recommended + * expect({a: 1}).to.not.eql({b: 2}); // Not recommended + * + * `.eql` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); + * + * The alias `.eqls` can be used interchangeably with `.eql`. + * + * The `.deep.equal` assertion is almost identical to `.eql` but with one + * difference: `.deep.equal` causes deep equality comparisons to also be used + * for any other assertions that follow in the chain. + * + * @name eql + * @alias eqls + * @param {Mixed} obj + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + this.assert( + _.eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(n[, msg]) + * + * Asserts that the target is a number or a date greater than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.above(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is greater than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.above(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.above`. + * + * expect(2).to.equal(2); // Recommended + * expect(1).to.not.be.above(2); // Not recommended + * + * `.above` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.above(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.above(2); + * + * The aliases `.gt` and `.greaterThan` can be used interchangeably with + * `.above`. + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to above must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to above must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len > n + , 'expected #{this} to have a length above #{exp} but got #{act}' + , 'expected #{this} to not have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above #{exp}' + , 'expected #{this} to be at most #{exp}' + , n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(n[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `n` respectively. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.at.least(1); // Not recommended + * expect(2).to.be.at.least(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is greater than or equal to the given number + * `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.least(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.least`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.at.least(2); // Not recommended + * + * `.least` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.at.least(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.at.least(2); + * + * The alias `.gte` can be used interchangeably with `.least`. + * + * @name least + * @alias gte + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to least must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to least must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len >= n + , 'expected #{this} to have a length at least #{exp} but got #{act}' + , 'expected #{this} to have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least #{exp}' + , 'expected #{this} to be below #{exp}' + , n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + + /** + * ### .below(n[, msg]) + * + * Asserts that the target is a number or a date less than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.below(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is less than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.below(4); // Not recommended + * + * expect([1, 2, 3]).to.have.length(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.below`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.below(1); // Not recommended + * + * `.below` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.below(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.below(1); + * + * The aliases `.lt` and `.lessThan` can be used interchangeably with + * `.below`. + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to below must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to below must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len < n + , 'expected #{this} to have a length below #{exp} but got #{act}' + , 'expected #{this} to not have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below #{exp}' + , 'expected #{this} to be at least #{exp}' + , n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(n[, msg]) + * + * Asserts that the target is a number or a date less than or equal to the given number + * or date `n` respectively. However, it's often best to assert that the target is equal to its + * expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.at.most(2); // Not recommended + * expect(1).to.be.at.most(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is less than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.most(4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.most`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.at.most(1); // Not recommended + * + * `.most` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.at.most(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.at.most(1); + * + * The alias `.lte` can be used interchangeably with `.most`. + * + * @name most + * @alias lte + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to most must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to most must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len <= n + , 'expected #{this} to have a length at most #{exp} but got #{act}' + , 'expected #{this} to have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most #{exp}' + , 'expected #{this} to be above #{exp}' + , n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + + /** + * ### .within(start, finish[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `start`, and less than or equal to the given number or date `finish` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.within(1, 3); // Not recommended + * expect(2).to.be.within(2, 3); // Not recommended + * expect(2).to.be.within(1, 2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is greater than or equal to the given number + * `start`, and less than or equal to the given number `finish`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.within`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.within(2, 4); // Not recommended + * + * `.within` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(4).to.be.within(1, 3, 'nooo why fail??'); + * expect(4, 'nooo why fail??').to.be.within(1, 3); + * + * @name within + * @param {Number} start lower bound inclusive + * @param {Number} finish upper bound inclusive + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , startType = _.type(start).toLowerCase() + , finishType = _.type(finish).toLowerCase() + , shouldThrow = true + , range = (startType === 'date' && finishType === 'date') + ? start.toUTCString() + '..' + finish.toUTCString() + : start + '..' + finish; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) { + errorMessage = msgPrefix + 'the arguments to within must be dates'; + } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the arguments to within must be numbers'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len >= start && len <= finish + , 'expected #{this} to have a length within ' + range + , 'expected #{this} to not have a length within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor[, msg]) + * + * Asserts that the target is an instance of the given `constructor`. + * + * function Cat () { } + * + * expect(new Cat()).to.be.an.instanceof(Cat); + * expect([1, 2]).to.be.an.instanceof(Array); + * + * Add `.not` earlier in the chain to negate `.instanceof`. + * + * expect({a: 1}).to.not.be.an.instanceof(Array); + * + * `.instanceof` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); + * + * Due to limitations in ES5, `.instanceof` may not always work as expected + * when using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing built-in object such as + * `Array`, `Error`, and `Map`. See your transpiler's docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * The alias `.instanceOf` can be used interchangeably with `.instanceof`. + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} msg _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + + var target = flag(this, 'object') + var ssfi = flag(this, 'ssfi'); + var flagMsg = flag(this, 'message'); + + try { + var isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The instanceof assertion needs a constructor but ' + + _.type(constructor) + ' was given.', + undefined, + ssfi + ); + } + throw err; + } + + var name = _.getName(constructor); + if (name === null) { + name = 'an unnamed constructor'; + } + + this.assert( + isInstanceOf + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name[, val[, msg]]) + * + * Asserts that the target has a property with the given key `name`. + * + * expect({a: 1}).to.have.property('a'); + * + * When `val` is provided, `.property` also asserts that the property's value + * is equal to the given `val`. + * + * expect({a: 1}).to.have.property('a', 1); + * + * By default, strict (`===`) equality is used. Add `.deep` earlier in the + * chain to use deep equality instead. See the `deep-eql` project page for + * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * The target's enumerable and non-enumerable properties are always included + * in the search. By default, both own and inherited properties are included. + * Add `.own` earlier in the chain to exclude inherited properties from the + * search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.own.property('a', 1); + * expect({a: 1}).to.have.property('b').but.not.own.property('b'); + * + * `.deep` and `.own` can be combined. + * + * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}) + * .to.have.deep.nested.property('a.b[0]', {c: 3}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.property`. + * + * expect({a: 1}).to.not.have.property('b'); + * + * However, it's dangerous to negate `.property` when providing `val`. The + * problem is that it creates uncertain expectations by asserting that the + * target either doesn't have a property with the given key `name`, or that it + * does have a property with the given key `name` but its value isn't equal to + * the given `val`. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target isn't expected to have a property with the given key + * `name`, it's often best to assert exactly that. + * + * expect({b: 2}).to.not.have.property('a'); // Recommended + * expect({b: 2}).to.not.have.property('a', 1); // Not recommended + * + * When the target is expected to have a property with the given key `name`, + * it's often best to assert that the property has its expected value, rather + * than asserting that it doesn't have one of many unexpected values. + * + * expect({a: 3}).to.have.property('a', 3); // Recommended + * expect({a: 3}).to.not.have.property('a', 1); // Not recommended + * + * `.property` changes the target of any assertions that follow in the chain + * to be the value of the property from the original target object. + * + * expect({a: 1}).to.have.property('a').that.is.a('number'); + * + * `.property` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing `val`, only use the + * second form. + * + * // Recommended + * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); + * expect({a: 1}, 'nooo why fail??').to.have.property('b'); + * + * // Not recommended + * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `val`. Instead, + * it's asserting that the target object has a `b` property that's equal to + * `undefined`. + * + * The assertions `.ownProperty` and `.haveOwnProperty` can be used + * interchangeably with `.own.property`. + * + * @name property + * @param {String} name + * @param {Mixed} val (optional) + * @param {String} msg _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + function assertProperty (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isNested = flag(this, 'nested') + , isOwn = flag(this, 'own') + , flagMsg = flag(this, 'message') + , obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi'); + + if (isNested && isOwn) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + undefined, + ssfi + ); + } + + if (obj === null || obj === undefined) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'Target cannot be null or undefined.', + undefined, + ssfi + ); + } + + var isDeep = flag(this, 'deep') + , negate = flag(this, 'negate') + , pathInfo = isNested ? _.getPathInfo(obj, name) : null + , value = isNested ? pathInfo.value : obj[name]; + + var descriptor = ''; + if (isDeep) descriptor += 'deep '; + if (isOwn) descriptor += 'own '; + if (isNested) descriptor += 'nested '; + descriptor += 'property '; + + var hasProperty; + if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) hasProperty = pathInfo.exists; + else hasProperty = _.hasProperty(obj, name); + + // When performing a negated assertion for both name and val, merely having + // a property with the given name isn't enough to cause the assertion to + // fail. It must both have a property with the given name, and the value of + // that property must equal the given val. Therefore, skip this assertion in + // favor of the next. + if (!negate || arguments.length === 1) { + this.assert( + hasProperty + , 'expected #{this} to have ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + hasProperty && (isDeep ? _.eql(val, value) : val === value) + , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + } + + Assertion.addMethod('property', assertProperty); + + function assertOwnProperty (name, value, msg) { + flag(this, 'own', true); + assertProperty.apply(this, arguments); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) + * + * Asserts that the target has its own property descriptor with the given key + * `name`. Enumerable and non-enumerable properties are included in the + * search. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a'); + * + * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that + * the property's descriptor is deeply equal to the given `descriptor`. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. + * + * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); + * + * However, it's dangerous to negate `.ownPropertyDescriptor` when providing + * a `descriptor`. The problem is that it creates uncertain expectations by + * asserting that the target either doesn't have a property descriptor with + * the given key `name`, or that it does have a property descriptor with the + * given key `name` but its not deeply equal to the given `descriptor`. It's + * often best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to have a property descriptor with the given + * key `name`, it's often best to assert exactly that. + * + * // Recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); + * + * // Not recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * When the target is expected to have a property descriptor with the given + * key `name`, it's often best to assert that the property has its expected + * descriptor, rather than asserting that it doesn't have one of many + * unexpected descriptors. + * + * // Recommended + * expect({a: 3}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 3, + * }); + * + * // Not recommended + * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * `.ownPropertyDescriptor` changes the target of any assertions that follow + * in the chain to be the value of the property descriptor from the original + * target object. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a') + * .that.has.property('enumerable', true); + * + * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a + * custom error message to show when the assertion fails. The message can also + * be given as the second argument to `expect`. When not providing + * `descriptor`, only use the second form. + * + * // Recommended + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }, 'nooo why fail??'); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); + * + * // Not recommended + * expect({a: 1}) + * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `descriptor`. + * Instead, it's asserting that the target object has a `b` property + * descriptor that's deeply equal to `undefined`. + * + * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with + * `.ownPropertyDescriptor`. + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + if (actualDescriptor && descriptor) { + this.assert( + _.eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .lengthOf(n[, msg]) + * + * Asserts that the target's `length` property is equal to the given number + * `n`. + * + * expect([1, 2, 3]).to.have.lengthOf(3); + * expect('foo').to.have.lengthOf(3); + * + * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often + * best to assert that the target's `length` property is equal to its expected + * value, rather than not equal to one of many unexpected values. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.not.have.lengthOf(4); // Not recommended + * + * `.lengthOf` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); + * + * `.lengthOf` can also be used as a language chain, causing all `.above`, + * `.below`, `.least`, `.most`, and `.within` assertions that follow in the + * chain to use the target's `length` property as the target. However, it's + * often best to assert that the target's `length` property is equal to its + * expected length, rather than asserting that its `length` property falls + * within some range of values. + * + * // Recommended + * expect([1, 2, 3]).to.have.lengthOf(3); + * + * // Not recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); + * expect([1, 2, 3]).to.have.lengthOf.below(4); + * expect([1, 2, 3]).to.have.lengthOf.at.least(3); + * expect([1, 2, 3]).to.have.lengthOf.at.most(3); + * expect([1, 2, 3]).to.have.lengthOf.within(2,4); + * + * Due to a compatibility issue, the alias `.length` can't be chained directly + * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used + * interchangeably with `.lengthOf` in every situation. It's recommended to + * always use `.lengthOf` instead of `.length`. + * + * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error + * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected + * + * @name lengthOf + * @alias length + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + var len = obj.length; + + this.assert( + len == n + , 'expected #{this} to have a length of #{exp} but got #{act}' + , 'expected #{this} to not have a length of #{act}' + , n + , len + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); + + /** + * ### .match(re[, msg]) + * + * Asserts that the target matches the given regular expression `re`. + * + * expect('foobar').to.match(/^foo/); + * + * Add `.not` earlier in the chain to negate `.match`. + * + * expect('foobar').to.not.match(/taco/); + * + * `.match` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect('foobar').to.match(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.match(/taco/); + * + * The alias `.matches` can be used interchangeably with `.match`. + * + * @name match + * @alias matches + * @param {RegExp} re + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(str[, msg]) + * + * Asserts that the target string contains the given substring `str`. + * + * expect('foobar').to.have.string('bar'); + * + * Add `.not` earlier in the chain to negate `.string`. + * + * expect('foobar').to.not.have.string('taco'); + * + * `.string` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect('foobar').to.have.string(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.have.string(/taco/); + * + * @name string + * @param {String} str + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + /** + * ### .keys(key1[, key2[, ...]]) + * + * Asserts that the target object, array, map, or set has the given keys. Only + * the target's own inherited properties are included in the search. + * + * When the target is an object or array, keys can be provided as one or more + * string arguments, a single array argument, or a single object argument. In + * the latter case, only the keys in the given object matter; the values are + * ignored. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * expect(['x', 'y']).to.have.all.keys(0, 1); + * + * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); + * expect(['x', 'y']).to.have.all.keys([0, 1]); + * + * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 + * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 + * + * When the target is a map or set, each key must be provided as a separate + * argument. + * + * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); + * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); + * + * Because `.keys` does different things based on the target's type, it's + * important to check the target's type before using `.keys`. See the `.a` doc + * for info on testing a target's type. + * + * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); + * + * By default, strict (`===`) equality is used to compare keys of maps and + * sets. Add `.deep` earlier in the chain to use deep equality instead. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); + * + * By default, the target must have all of the given keys and no more. Add + * `.any` earlier in the chain to only require that the target have at least + * one of the given keys. Also, add `.not` earlier in the chain to negate + * `.keys`. It's often best to add `.any` when negating `.keys`, and to use + * `.all` when asserting `.keys` without negation. + * + * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts + * exactly what's expected of the output, whereas `.not.all.keys` creates + * uncertain expectations. + * + * // Recommended; asserts that target doesn't have any of the given keys + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * // Not recommended; asserts that target doesn't have all of the given + * // keys but may or may not have some of them + * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); + * + * When asserting `.keys` without negation, `.all` is preferred because + * `.all.keys` asserts exactly what's expected of the output, whereas + * `.any.keys` creates uncertain expectations. + * + * // Recommended; asserts that target has all the given keys + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * // Not recommended; asserts that target has at least one of the given + * // keys but may or may not have more of them + * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` appear + * earlier in the chain. However, it's often best to add `.all` anyway because + * it improves readability. + * + * // Both assertions are identical + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended + * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended + * + * Add `.include` earlier in the chain to require that the target's keys be a + * superset of the expected keys, rather than identical sets. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * However, if `.any` and `.include` are combined, only the `.any` takes + * effect. The `.include` is ignored in this case. + * + * // Both assertions are identical + * expect({a: 1}).to.have.any.keys('a', 'b'); + * expect({a: 1}).to.include.any.keys('a', 'b'); + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.have.key('b'); + * + * The alias `.key` can be used interchangeably with `.keys`. + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , objType = _.type(obj) + , keysType = _.type(keys) + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , str + , deepStr = '' + , ok = true + , flagMsg = flag(this, 'message'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; + + if (objType === 'Map' || objType === 'Set') { + deepStr = isDeep ? 'deeply ' : ''; + actual = []; + + // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. + obj.forEach(function (val, key) { actual.push(key) }); + + if (keysType !== 'Array') { + keys = Array.prototype.slice.call(arguments); + } + + } else { + actual = _.getOwnEnumerableProperties(obj); + + switch (keysType) { + case 'Array': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + break; + case 'Object': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + // Only stringify non-Symbols because Symbols would become "Symbol()" + keys = keys.map(function (val) { + return typeof val === 'symbol' ? val : String(val); + }); + } + + if (!keys.length) { + throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); + } + + var len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all') + , expected = keys + , actual; + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + ok = expected.some(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + } + + // Has all + if (all) { + ok = expected.every(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + + if (!flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key) { + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + deepStr + str + , 'expected #{this} to not ' + deepStr + str + , expected.slice(0).sort(_.compareByInspect) + , actual.sort(_.compareByInspect) + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw([errorLike], [errMsgMatcher], [msg]) + * + * When no arguments are provided, `.throw` invokes the target function and + * asserts that an error is thrown. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(); + * + * When one argument is provided, and it's an error constructor, `.throw` + * invokes the target function and asserts that an error is thrown that's an + * instance of that error constructor. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError); + * + * When one argument is provided, and it's an error instance, `.throw` invokes + * the target function and asserts that an error is thrown that's strictly + * (`===`) equal to that error instance. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(err); + * + * When one argument is provided, and it's a string, `.throw` invokes the + * target function and asserts that an error is thrown with a message that + * contains that string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw('salmon'); + * + * When one argument is provided, and it's a regular expression, `.throw` + * invokes the target function and asserts that an error is thrown with a + * message that matches that regular expression. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(/salmon/); + * + * When two arguments are provided, and the first is an error instance or + * constructor, and the second is a string or regular expression, `.throw` + * invokes the function and asserts that an error is thrown that fulfills both + * conditions as described above. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); + * expect(badFn).to.throw(TypeError, /salmon/); + * expect(badFn).to.throw(err, 'salmon'); + * expect(badFn).to.throw(err, /salmon/); + * + * Add `.not` earlier in the chain to negate `.throw`. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); + * + * However, it's dangerous to negate `.throw` when providing any arguments. + * The problem is that it creates uncertain expectations by asserting that the + * target either doesn't throw an error, or that it throws an error but of a + * different type than the given type, or that it throws an error of the given + * type but with a message that doesn't include the given string. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to throw an error, it's often best to assert + * exactly that. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); // Recommended + * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * When the target is expected to throw an error, it's often best to assert + * that the error is of its expected type, and has a message that includes an + * expected string, rather than asserting that it doesn't have one of many + * unexpected types, and doesn't have a message that includes some string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended + * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * `.throw` changes the target of any assertions that follow in the chain to + * be the error object that's thrown. + * + * var err = new TypeError('Illegal salmon!'); + * err.code = 42; + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError).with.property('code', 42); + * + * `.throw` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. When not providing two arguments, always use + * the second form. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); + * expect(goodFn, 'nooo why fail??').to.throw(); + * + * Due to limitations in ES5, `.throw` may not always work as expected when + * using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing the built-in `Error` object and + * then passing the subclassed constructor to `.throw`. See your transpiler's + * docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * Beware of some common mistakes when using the `throw` assertion. One common + * mistake is to accidentally invoke the function yourself instead of letting + * the `throw` assertion invoke the function for you. For example, when + * testing if a function named `fn` throws, provide `fn` instead of `fn()` as + * the target for the assertion. + * + * expect(fn).to.throw(); // Good! Tests `fn` as desired + * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` + * + * If you need to assert that your function `fn` throws when passed certain + * arguments, then wrap a call to `fn` inside of another function. + * + * expect(function () { fn(42); }).to.throw(); // Function expression + * expect(() => fn(42)).to.throw(); // ES6 arrow function + * + * Another common mistake is to provide an object method (or any stand-alone + * function that relies on `this`) as the target of the assertion. Doing so is + * problematic because the `this` context will be lost when the function is + * invoked by `.throw`; there's no way for it to know what `this` is supposed + * to be. There are two ways around this problem. One solution is to wrap the + * method or function call inside of another function. Another solution is to + * use `bind`. + * + * expect(function () { cat.meow(); }).to.throw(); // Function expression + * expect(() => cat.meow()).to.throw(); // ES6 arrow function + * expect(cat.meow.bind(cat)).to.throw(); // Bind + * + * Finally, it's worth mentioning that it's a best practice in JavaScript to + * only throw `Error` and derivatives of `Error` such as `ReferenceError`, + * `TypeError`, and user-defined objects that extend `Error`. No other type of + * value will generate a stack trace when initialized. With that said, the + * `throw` assertion does technically support any type of value being thrown, + * not just `Error` and its derivatives. + * + * The aliases `.throws` and `.Throw` can be used interchangeably with + * `.throw`. + * + * @name throw + * @alias throws + * @alias Throw + * @param {Error|ErrorConstructor} errorLike + * @param {String|RegExp} errMsgMatcher error message + * @param {String} msg _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (errorLike, errMsgMatcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') || false; + new Assertion(obj, flagMsg, ssfi, true).is.a('function'); + + if (errorLike instanceof RegExp || typeof errorLike === 'string') { + errMsgMatcher = errorLike; + errorLike = null; + } + + var caughtErr; + try { + obj(); + } catch (err) { + caughtErr = err; + } + + // If we have the negate flag enabled and at least one valid argument it means we do expect an error + // but we want it to match a given set of criteria + var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; + + // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible + // See Issue #551 and PR #683@GitHub + var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + var errorLikeFail = false; + var errMsgMatcherFail = false; + + // Checking if error was thrown + if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { + // We need this to display results correctly according to their types + var errorLikeString = 'an error'; + if (errorLike instanceof Error) { + errorLikeString = '#{exp}'; + } else if (errorLike) { + errorLikeString = _.checkError.getConstructorName(errorLike); + } + + this.assert( + caughtErr + , 'expected #{this} to throw ' + errorLikeString + , 'expected #{this} to not throw an error but #{act} was thrown' + , errorLike && errorLike.toString() + , (caughtErr instanceof Error ? + caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr && + _.checkError.getConstructorName(caughtErr))) + ); + } + + if (errorLike && caughtErr) { + // We should compare instances only if `errorLike` is an instance of `Error` + if (errorLike instanceof Error) { + var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); + + if (isCompatibleInstance === negate) { + // These checks were created to ensure we won't fail too soon when we've got both args and a negate + // See Issue #551 and PR #683@GitHub + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '') + , errorLike.toString() + , caughtErr.toString() + ); + } + } + } + + var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + } + } + + if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { + // Here we check compatible messages + var placeholder = 'including'; + if (errMsgMatcher instanceof RegExp) { + placeholder = 'matching' + } + + var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}' + , 'expected #{this} to throw error not ' + placeholder + ' #{exp}' + , errMsgMatcher + , _.checkError.getMessage(caughtErr) + ); + } + } + } + + // If both assertions failed and both should've matched we throw an error + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + + flag(this, 'object', caughtErr); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method[, msg]) + * + * When the target is a non-function object, `.respondTo` asserts that the + * target has a method with the given name `method`. The method can be own or + * inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.respondTo('meow'); + * + * When the target is a function, `.respondTo` asserts that the target's + * `prototype` property has a method with the given name `method`. Again, the + * method can be own or inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(Cat).to.respondTo('meow'); + * + * Add `.itself` earlier in the chain to force `.respondTo` to treat the + * target as a non-function object, even if it's a function. Thus, it asserts + * that the target has a method with the given name `method`, rather than + * asserting that the target's `prototype` property has a method with the + * given name `method`. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * When not adding `.itself`, it's important to check the target's type before + * using `.respondTo`. See the `.a` doc for info on checking a target's type. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); + * + * Add `.not` earlier in the chain to negate `.respondTo`. + * + * function Dog () {} + * Dog.prototype.bark = function () {}; + * + * expect(new Dog()).to.not.respondTo('meow'); + * + * `.respondTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect({}).to.respondTo('meow', 'nooo why fail??'); + * expect({}, 'nooo why fail??').to.respondTo('meow'); + * + * The alias `.respondsTo` can be used interchangeably with `.respondTo`. + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === typeof obj && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Forces all `.respondTo` assertions that follow in the chain to behave as if + * the target is a non-function object, even if it's a function. Thus, it + * causes `.respondTo` to assert that the target has a method with the given + * name, rather than asserting that the target's `prototype` property has a + * method with the given name. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(matcher[, msg]) + * + * Invokes the given `matcher` function with the target being passed as the + * first argument, and asserts that the value returned is truthy. + * + * expect(1).to.satisfy(function(num) { + * return num > 0; + * }); + * + * Add `.not` earlier in the chain to negate `.satisfy`. + * + * expect(1).to.not.satisfy(function(num) { + * return num > 2; + * }); + * + * `.satisfy` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.satisfy(function(num) { + * return num > 2; + * }, 'nooo why fail??'); + * + * expect(1, 'nooo why fail??').to.satisfy(function(num) { + * return num > 2; + * }); + * + * The alias `.satisfies` can be used interchangeably with `.satisfy`. + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , flag(this, 'negate') ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta[, msg]) + * + * Asserts that the target is a number that's within a given +/- `delta` range + * of the given number `expected`. However, it's often best to assert that the + * target is equal to its expected value. + * + * // Recommended + * expect(1.5).to.equal(1.5); + * + * // Not recommended + * expect(1.5).to.be.closeTo(1, 0.5); + * expect(1.5).to.be.closeTo(2, 0.5); + * expect(1.5).to.be.closeTo(1, 1); + * + * Add `.not` earlier in the chain to negate `.closeTo`. + * + * expect(1.5).to.equal(1.5); // Recommended + * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended + * + * `.closeTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); + * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); + * + * The alias `.approximately` can be used interchangeably with `.closeTo`. + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).is.a('number'); + if (typeof expected !== 'number' || typeof delta !== 'number') { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'the arguments to closeTo or approximately must be numbers', + undefined, + ssfi + ); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + // Note: Duplicates are ignored if testing for inclusion instead of sameness. + function isSubsetOf(subset, superset, cmp, contains, ordered) { + if (!contains) { + if (subset.length !== superset.length) return false; + superset = superset.slice(); + } + + return subset.every(function(elem, idx) { + if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + + if (!cmp) { + var matchIdx = superset.indexOf(elem); + if (matchIdx === -1) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + } + + return superset.some(function(elem2, matchIdx) { + if (!cmp(elem, elem2)) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + }); + }); + } + + /** + * ### .members(set[, msg]) + * + * Asserts that the target array has the same members as the given array + * `set`. + * + * expect([1, 2, 3]).to.have.members([2, 1, 3]); + * expect([1, 2, 2]).to.have.members([2, 1, 2]); + * + * By default, members are compared using strict (`===`) equality. Add `.deep` + * earlier in the chain to use deep equality instead. See the `deep-eql` + * project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * By default, order doesn't matter. Add `.ordered` earlier in the chain to + * require that members appear in the same order. + * + * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); + * expect([1, 2, 3]).to.have.members([2, 1, 3]) + * .but.not.ordered.members([2, 1, 3]); + * + * By default, both arrays must be the same size. Add `.include` earlier in + * the chain to require that the target's members be a superset of the + * expected members. Note that duplicates are ignored in the subset when + * `.include` is added. + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * `.deep`, `.ordered`, and `.include` can all be combined. However, if + * `.include` and `.ordered` are combined, the ordering begins at the start of + * both arrays. + * + * expect([{a: 1}, {b: 2}, {c: 3}]) + * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) + * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); + * + * Add `.not` earlier in the chain to negate `.members`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the target array doesn't have all of the same members as + * the given array `set` but may or may not have some of them. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended + * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended + * + * `.members` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); + * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); + * + * @name members + * @param {Array} set + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).to.be.an('array'); + new Assertion(subset, flagMsg, ssfi, true).to.be.an('array'); + + var contains = flag(this, 'contains'); + var ordered = flag(this, 'ordered'); + + var subject, failMsg, failNegateMsg, lengthCheck; + + if (contains) { + subject = ordered ? 'an ordered superset' : 'a superset'; + failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; + failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; + } else { + subject = ordered ? 'ordered members' : 'members'; + failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; + failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; + } + + var cmp = flag(this, 'deep') ? _.eql : undefined; + + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered) + , failMsg + , failNegateMsg + , subset + , obj + , true + ); + }); + + /** + * ### .oneOf(list[, msg]) + * + * Asserts that the target is a member of the given array `list`. However, + * it's often best to assert that the target is equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended + * + * Comparisons are performed using strict (`===`) equality. + * + * Add `.not` earlier in the chain to negate `.oneOf`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended + * + * `.oneOf` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); + + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + + Assertion.addMethod('oneOf', oneOf); + + + /** + * ### .change(subject[, prop[, msg]]) + * + * When one argument is provided, `.change` asserts that the given function + * `subject` returns a different value when it's invoked before the target + * function compared to when it's invoked afterward. However, it's often best + * to assert that `subject` is equal to its expected value. + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * // Recommended + * expect(getDots()).to.equal(''); + * addDot(); + * expect(getDots()).to.equal('.'); + * + * // Not recommended + * expect(addDot).to.change(getDots); + * + * When two arguments are provided, `.change` asserts that the value of the + * given object `subject`'s `prop` property is different before invoking the + * target function compared to afterward. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * // Recommended + * expect(myObj).to.have.property('dots', ''); + * addDot(); + * expect(myObj).to.have.property('dots', '.'); + * + * // Not recommended + * expect(addDot).to.change(myObj, 'dots'); + * + * Strict (`===`) equality is used to compare before and after values. + * + * Add `.not` earlier in the chain to negate `.change`. + * + * var dots = '' + * , noop = function () {} + * , getDots = function () { return dots; }; + * + * expect(noop).to.not.change(getDots); + * + * var myObj = {dots: ''} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'dots'); + * + * `.change` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * expect(addDot, 'nooo why fail??').to.not.change(getDots); + * + * `.change` also causes all `.by` assertions that follow in the chain to + * assert how much a numeric subject was increased or decreased by. However, + * it's dangerous to use `.change.by`. The problem is that it creates + * uncertain expectations by asserting that the subject either increases by + * the given delta, or that it decreases by the given delta. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * The alias `.changes` can be used interchangeably with `.change`. + * + * @name change + * @alias changes + * @param {String} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + // This gets flagged because of the .by(delta) assertion + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'change'); + flag(this, 'realDelta', final !== initial); + + this.assert( + initial !== final + , 'expected ' + msgObj + ' to change' + , 'expected ' + msgObj + ' to not change' + ); + } + + Assertion.addMethod('change', assertChanges); + Assertion.addMethod('changes', assertChanges); + + /** + * ### .increase(subject[, prop[, msg]]) + * + * When one argument is provided, `.increase` asserts that the given function + * `subject` returns a greater number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.increase` also + * causes all `.by` assertions that follow in the chain to assert how much + * greater of a number is returned. It's often best to assert that the return + * value increased by the expected amount, rather than asserting it increased + * by any amount. + * + * var val = 1 + * , addTwo = function () { val += 2; } + * , getVal = function () { return val; }; + * + * expect(addTwo).to.increase(getVal).by(2); // Recommended + * expect(addTwo).to.increase(getVal); // Not recommended + * + * When two arguments are provided, `.increase` asserts that the value of the + * given object `subject`'s `prop` property is greater after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.increase(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.increase`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either decreases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to decrease, it's often best to assert that it + * decreased by the expected amount. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.increase(myObj, 'val'); // Not recommended + * + * `.increase` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.increase(getVal); + * + * The alias `.increases` can be used interchangeably with `.increase`. + * + * @name increase + * @alias increases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'increase'); + flag(this, 'realDelta', final - initial); + + this.assert( + final - initial > 0 + , 'expected ' + msgObj + ' to increase' + , 'expected ' + msgObj + ' to not increase' + ); + } + + Assertion.addMethod('increase', assertIncreases); + Assertion.addMethod('increases', assertIncreases); + + /** + * ### .decrease(subject[, prop[, msg]]) + * + * When one argument is provided, `.decrease` asserts that the given function + * `subject` returns a lesser number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.decrease` also + * causes all `.by` assertions that follow in the chain to assert how much + * lesser of a number is returned. It's often best to assert that the return + * value decreased by the expected amount, rather than asserting it decreased + * by any amount. + * + * var val = 1 + * , subtractTwo = function () { val -= 2; } + * , getVal = function () { return val; }; + * + * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended + * expect(subtractTwo).to.decrease(getVal); // Not recommended + * + * When two arguments are provided, `.decrease` asserts that the value of the + * given object `subject`'s `prop` property is lesser after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.decrease`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either increases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to increase, it's often best to assert that it + * increased by the expected amount. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended + * + * `.decrease` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.decrease(getVal); + * + * The alias `.decreases` can be used interchangeably with `.decrease`. + * + * @name decrease + * @alias decreases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'decrease'); + flag(this, 'realDelta', initial - final); + + this.assert( + final - initial < 0 + , 'expected ' + msgObj + ' to decrease' + , 'expected ' + msgObj + ' to not decrease' + ); + } + + Assertion.addMethod('decrease', assertDecreases); + Assertion.addMethod('decreases', assertDecreases); + + /** + * ### .by(delta[, msg]) + * + * When following an `.increase` assertion in the chain, `.by` asserts that + * the subject of the `.increase` assertion increased by the given `delta`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * When following a `.decrease` assertion in the chain, `.by` asserts that the + * subject of the `.decrease` assertion decreased by the given `delta`. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); + * + * When following a `.change` assertion in the chain, `.by` asserts that the + * subject of the `.change` assertion either increased or decreased by the + * given `delta`. However, it's dangerous to use `.change.by`. The problem is + * that it creates uncertain expectations. It's often best to identify the + * exact output that's expected, and then write an assertion that only accepts + * that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.by`. However, it's often best + * to assert that the subject changed by its expected delta, rather than + * asserting that it didn't change by one of countless unexpected deltas. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * // Recommended + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * // Not recommended + * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); + * + * `.by` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); + * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); + * + * @name by + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDelta(delta, msg) { + if (msg) flag(this, 'message', msg); + + var msgObj = flag(this, 'deltaMsgObj'); + var initial = flag(this, 'initialDeltaValue'); + var final = flag(this, 'finalDeltaValue'); + var behavior = flag(this, 'deltaBehavior'); + var realDelta = flag(this, 'realDelta'); + + var expression; + if (behavior === 'change') { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + + this.assert( + expression + , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta + , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta + ); + } + + Assertion.addMethod('by', assertDelta); + + /** + * ### .extensible + * + * Asserts that the target is extensible, which means that new properties can + * be added to it. Primitives are never extensible. + * + * expect({a: 1}).to.be.extensible; + * + * Add `.not` earlier in the chain to negate `.extensible`. + * + * var nonExtensibleObject = Object.preventExtensions({}) + * , sealedObject = Object.seal({}) + * , frozenObject = Object.freeze({}); + * + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * expect(1).to.not.be.extensible; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(1, 'nooo why fail??').to.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior for ES5 environments. + + var isExtensible = obj === Object(obj) && Object.isExtensible(obj); + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed, which means that new properties can't be + * added to it, and its existing properties can't be reconfigured or deleted. + * However, it's possible that its existing properties can still be reassigned + * to different values. Primitives are always sealed. + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect(1).to.be.sealed; + * + * Add `.not` earlier in the chain to negate `.sealed`. + * + * expect({a: 1}).to.not.be.sealed; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior for ES5 environments. + + var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen, which means that new properties can't be + * added to it, and its existing properties can't be reassigned to different + * values, reconfigured, or deleted. Primitives are always frozen. + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect(1).to.be.frozen; + * + * Add `.not` earlier in the chain to negate `.frozen`. + * + * expect({a: 1}).to.not.be.frozen; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior for ES5 environments. + + var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); + + /** + * ### .finite + * + * Asserts that the target is a number, and isn't `NaN` or positive/negative + * `Infinity`. + * + * expect(1).to.be.finite; + * + * Add `.not` earlier in the chain to negate `.finite`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either isn't a number, or that it's `NaN`, or + * that it's positive `Infinity`, or that it's negative `Infinity`. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to be a number, it's often best to assert + * that it's the expected type, rather than asserting that it isn't one of + * many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.finite; // Not recommended + * + * When the target is expected to be `NaN`, it's often best to assert exactly + * that. + * + * expect(NaN).to.be.NaN; // Recommended + * expect(NaN).to.not.be.finite; // Not recommended + * + * When the target is expected to be positive infinity, it's often best to + * assert exactly that. + * + * expect(Infinity).to.equal(Infinity); // Recommended + * expect(Infinity).to.not.be.finite; // Not recommended + * + * When the target is expected to be negative infinity, it's often best to + * assert exactly that. + * + * expect(-Infinity).to.equal(-Infinity); // Recommended + * expect(-Infinity).to.not.be.finite; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect('foo', 'nooo why fail??').to.be.finite; + * + * @name finite + * @namespace BDD + * @api public + */ + + Assertion.addProperty('finite', function(msg) { + var obj = flag(this, 'object'); + + this.assert( + typeof obj === "number" && isFinite(obj) + , 'expected #{this} to be a finite number' + , 'expected #{this} to not be a finite number' + ); + }); +}; + +},{}],6:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + + +module.exports = function (chai, util) { + + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert, true); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg, assert.isOk, true).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg, assert.isNotOk, true).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal, true); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual, true); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @alias deepStrictEqual + * @namespace Assert + * @api public + */ + + assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg, assert.isTrue, true).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg, assert.isFalse, true).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg, assert.isNull, true).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); + }; + + /** + * ### .isNaN + * + * Asserts that value is NaN. + * + * assert.isNaN(NaN, 'NaN is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg, assert.isNaN, true).to.be.NaN; + }; + + /** + * ### .isNotNaN + * + * Asserts that value is not NaN. + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN; + }; + + /** + * ### .exists + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * assert.exists(foo, 'foo is neither `null` nor `undefined`'); + * + * @name exists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.exists = function (val, msg) { + new Assertion(val, msg, assert.exists, true).to.exist; + }; + + /** + * ### .notExists + * + * Asserts that the target is either `null` or `undefined`. + * + * var bar = null + * , baz; + * + * assert.notExists(bar); + * assert.notExists(baz, 'baz is either null or undefined'); + * + * @name notExists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notExists = function (val, msg) { + new Assertion(val, msg, assert.notExists, true).to.not.exist; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg, assert.isFunction, true).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg, assert.isObject, true).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg, assert.isArray, true).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg, assert.isString, true).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); + }; + + /** + * ### .isFinite(value, [message]) + * + * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * var cups = 2; + * assert.isFinite(cups, 'how many cups'); + * + * assert.isFinite(NaN); // throws + * + * @name isFinite + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFinite = function (val, msg) { + new Assertion(val, msg, assert.isFinite, true).to.be.finite; + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg, assert.typeOf, true).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.notInstanceOf, true) + .to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.include([1,2,3], 2, 'array contains value'); + * assert.include('foobar', 'foo', 'string contains substring'); + * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); + * + * Strict equality (===) is used. When asserting the inclusion of a value in + * an array, the array is searched for an element that's strictly equal to the + * given value. When asserting a subset of properties in an object, the object + * is searched for the given property keys, checking that each one is present + * and stricty equal to the given property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.include([obj1, obj2], obj1); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include, true).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.notInclude([1,2,3], 4, 'array doesn't contain value'); + * assert.notInclude('foobar', 'baz', 'string doesn't contain substring'); + * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); + * + * Strict equality (===) is used. When asserting the absence of a value in an + * array, the array is searched to confirm the absence of an element that's + * strictly equal to the given value. When asserting a subset of properties in + * an object, the object is searched to confirm that at least one of the given + * property keys is either not present or not strictly equal to the given + * property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notInclude([obj1, obj2], {a: 1}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude, true).not.include(inc); + }; + + /** + * ### .deepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.deepInclude([obj1, obj2], {a: 1}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); + * + * @name deepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); + }; + + /** + * ### .notDeepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notDeepInclude([obj1, obj2], {a: 9}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); + * + * @name notDeepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); + }; + + /** + * ### .nestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); + * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); + * + * @name nestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); + }; + + /** + * ### .notNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); + * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); + * + * @name notNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notNestedInclude, true) + .not.nested.include(inc); + }; + + /** + * ### .deepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); + * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); + * + * @name deepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepNestedInclude, true) + .deep.nested.include(inc); + }; + + /** + * ### .notDeepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) + * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); + * + * @name notDeepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepNestedInclude, true) + .not.deep.nested.include(inc); + }; + + /** + * ### .ownInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties. + * + * assert.ownInclude({ a: 1 }, { a: 1 }); + * + * @name ownInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.ownInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); + }; + + /** + * ### .notOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties. + * + * Object.prototype.b = 2; + * + * assert.notOwnInclude({ a: 1 }, { b: 2 }); + * + * @name notOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); + }; + + /** + * ### .deepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); + * + * @name deepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepOwnInclude, true) + .deep.own.include(inc); + }; + + /** + * ### .notDeepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); + * + * @name notDeepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepOwnInclude, true) + .not.deep.own.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg, assert.match, true).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * assert.property({ tea: { green: 'matcha' }}, 'toString'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg, assert.property, true).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notProperty, true) + .to.not.have.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a strict equality check + * (===). + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.propertyVal, true) + .to.have.property(prop, val); + }; + + /** + * ### .notPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a strict equality check + * (===). + * + * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); + * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); + * + * @name notPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notPropertyVal, true) + .to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a deep equality check. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepPropertyVal, true) + .to.have.deep.property(prop, val); + }; + + /** + * ### .notDeepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a deep equality check. + * + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * + * @name notDeepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepPropertyVal, true) + .to.not.have.deep.property(prop, val); + }; + + /** + * ### .ownProperty(object, property, [message]) + * + * Asserts that `object` has a direct property named by `property`. Inherited + * properties aren't checked. + * + * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); + * + * @name ownProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.ownProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.ownProperty, true) + .to.have.own.property(prop); + }; + + /** + * ### .notOwnProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct property named by + * `property`. Inherited properties aren't checked. + * + * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); + * assert.notOwnProperty({}, 'toString'); + * + * @name notOwnProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.notOwnProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notOwnProperty, true) + .to.not.have.own.property(prop); + }; + + /** + * ### .ownPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a strict equality check (===). + * Inherited properties aren't checked. + * + * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); + * + * @name ownPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.ownPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.ownPropertyVal, true) + .to.have.own.property(prop, value); + }; + + /** + * ### .notOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a strict equality check + * (===). Inherited properties aren't checked. + * + * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); + * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notOwnPropertyVal, true) + .to.not.have.own.property(prop, value); + }; + + /** + * ### .deepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a deep equality check. Inherited + * properties aren't checked. + * + * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.deepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.deepOwnPropertyVal, true) + .to.have.deep.own.property(prop, value); + }; + + /** + * ### .notDeepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a deep equality check. + * Inherited properties aren't checked. + * + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notDeepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true) + .to.not.have.deep.own.property(prop, value); + }; + + /** + * ### .nestedProperty(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`, which can be a string using dot- and bracket-notation for + * nested reference. + * + * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name nestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.nestedProperty, true) + .to.have.nested.property(prop); + }; + + /** + * ### .notNestedProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for nested reference. The + * property cannot exist on the object nor anywhere in its prototype chain. + * + * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notNestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notNestedProperty, true) + .to.not.have.nested.property(prop); + }; + + /** + * ### .nestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a strict equality check (===). + * + * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name nestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.nestedPropertyVal, true) + .to.have.nested.property(prop, val); + }; + + /** + * ### .notNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a strict equality check (===). + * + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); + * + * @name notNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notNestedPropertyVal, true) + .to.not.have.nested.property(prop, val); + }; + + /** + * ### .deepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with a value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a deep equality check. + * + * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); + * + * @name deepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepNestedPropertyVal, true) + .to.have.deep.nested.property(prop, val); + }; + + /** + * ### .notDeepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a deep equality check. + * + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); + * + * @name notDeepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true) + .to.not.have.deep.nested.property(prop, val); + } + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` property with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); + }; + + /** + * ### .hasAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); + * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAnyKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); + } + + /** + * ### .hasAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); + * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); + } + + /** + * ### .containsAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name containsAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllKeys, true) + .to.contain.all.keys(keys); + } + + /** + * ### .doesNotHaveAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAnyKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true) + .to.not.have.any.keys(keys); + } + + /** + * ### .doesNotHaveAllKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllKeys, true) + .to.not.have.all.keys(keys); + } + + /** + * ### .hasAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyDeepKeys, true) + .to.have.any.deep.keys(keys); + } + + /** + * ### .hasAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); + * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllDeepKeys, true) + .to.have.all.deep.keys(keys); + } + + /** + * ### .containsAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name containsAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllDeepKeys, true) + .to.contain.all.deep.keys(keys); + } + + /** + * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAnyDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true) + .to.not.have.any.deep.keys(keys); + } + + /** + * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true) + .to.not.have.all.deep.keys(keys); + } + + /** + * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a + * message matching `errMsgMatcher`. + * + * assert.throws(fn, 'function throws a reference error'); + * assert.throws(fn, /function throws a reference error/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, errorInstance); + * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); + * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); + * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); + * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} fn + * @param {ErrorConstructor|Error} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + var assertErr = new Assertion(fn, msg, assert.throws, true) + .to.throw(errorLike, errMsgMatcher); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a + * message matching `errMsgMatcher`. + * + * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); + * assert.doesNotThrow(fn, /Any Error thrown must not match this/); + * assert.doesNotThrow(fn, Error); + * assert.doesNotThrow(fn, errorInstance); + * assert.doesNotThrow(fn, Error, 'Error must not have this message'); + * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); + * assert.doesNotThrow(fn, Error, /Error must not match this/); + * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); + * + * @name doesNotThrow + * @param {Function} fn + * @param {ErrorConstructor} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + new Assertion(fn, msg, assert.doesNotThrow, true) + .to.not.throw(errorLike, errMsgMatcher); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + msg = msg ? msg + ': ' : msg; + throw new chai.AssertionError( + msg + 'Invalid operator "' + operator + '"', + undefined, + assert.operator + ); + } + var test = new Assertion(ok, msg, assert.operator, true); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.approximately, true) + .to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * strict equality check (===). + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameMembers, true) + .to.have.same.members(set2); + } + + /** + * ### .notSameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a strict equality check (===). + * + * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); + * + * @name notSameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameMembers, true) + .to.not.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * deep equality check. + * + * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepMembers, true) + .to.have.same.deep.members(set2); + } + + /** + * ### .notSameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a deep equality check. + * + * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); + * + * @name notSameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepMembers, true) + .to.not.have.same.deep.members(set2); + } + + /** + * ### .sameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a strict equality check (===). + * + * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); + * + * @name sameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameOrderedMembers, true) + .to.have.same.ordered.members(set2); + } + + /** + * ### .notSameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a strict equality check (===). + * + * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); + * + * @name notSameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameOrderedMembers, true) + .to.not.have.same.ordered.members(set2); + } + + /** + * ### .sameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a deep equality check. + * + * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); + * + * @name sameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepOrderedMembers, true) + .to.have.same.deep.ordered.members(set2); + } + + /** + * ### .notSameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a deep equality check. + * + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); + * + * @name notSameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true) + .to.not.have.same.deep.ordered.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeMembers, true) + .to.include.members(subset); + } + + /** + * ### .notIncludeMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); + * + * @name notIncludeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeMembers, true) + .to.not.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a deep + * equality check. Duplicates are ignored. + * + * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepMembers, true) + .to.include.deep.members(subset); + } + + /** + * ### .notIncludeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * deep equality check. Duplicates are ignored. + * + * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); + * + * @name notIncludeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepMembers, true) + .to.not.include.deep.members(subset); + } + + /** + * ### .includeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); + * + * @name includeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeOrderedMembers, true) + .to.include.ordered.members(subset); + } + + /** + * ### .notIncludeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); + * + * @name notIncludeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeOrderedMembers, true) + .to.not.include.ordered.members(subset); + } + + /** + * ### .includeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); + * + * @name includeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepOrderedMembers, true) + .to.include.deep.ordered.members(subset); + } + + /** + * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); + * + * @name notIncludeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true) + .to.not.include.deep.ordered.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property, [message]) + * + * Asserts that a function changes the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); + } + + /** + * ### .changesBy(function, object, property, delta, [message]) + * + * Asserts that a function changes the value of a property by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 2 }; + * assert.changesBy(fn, obj, 'val', 2); + * + * @name changesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesBy, true) + .to.change(obj, prop).by(delta); + } + + /** + * ### .doesNotChange(function, object, property, [message]) + * + * Asserts that a function does not change the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotChange, true) + .to.not.change(obj, prop); + } + + /** + * ### .changesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.changesButNotBy(fn, obj, 'val', 5); + * + * @name changesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesButNotBy, true) + .to.change(obj, prop).but.not.by(delta); + } + + /** + * ### .increases(function, object, property, [message]) + * + * Asserts that a function increases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.increases, true) + .to.increase(obj, prop); + } + + /** + * ### .increasesBy(function, object, property, delta, [message]) + * + * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.increasesBy(fn, obj, 'val', 10); + * + * @name increasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesBy, true) + .to.increase(obj, prop).by(delta); + } + + /** + * ### .doesNotIncrease(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotIncrease, true) + .to.not.increase(obj, prop); + } + + /** + * ### .increasesButNotBy(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.increasesButNotBy(fn, obj, 'val', 10); + * + * @name increasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesButNotBy, true) + .to.increase(obj, prop).but.not.by(delta); + } + + /** + * ### .decreases(function, object, property, [message]) + * + * Asserts that a function decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.decreases, true) + .to.decrease(obj, prop); + } + + /** + * ### .decreasesBy(function, object, property, delta, [message]) + * + * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val -= 5 }; + * assert.decreasesBy(fn, obj, 'val', 5); + * + * @name decreasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesBy, true) + .to.decrease(obj, prop).by(delta); + } + + /** + * ### .doesNotDecrease(function, object, property, [message]) + * + * Asserts that a function does not decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecrease, true) + .to.not.decrease(obj, prop); + } + + /** + * ### .doesNotDecreaseBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.doesNotDecreaseBy(fn, obj, 'val', 1); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecreaseBy, true) + .to.not.decrease(obj, prop).by(delta); + } + + /** + * ### .decreasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreasesButNotBy(fn, obj, 'val', 1); + * + * @name decreasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesButNotBy, true) + .to.decrease(obj, prop).but.not.by(delta); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; + }; + + /** + * ### .isEmpty(target) + * + * Asserts that the target does not contain any values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isEmpty([]); + * assert.isEmpty(''); + * assert.isEmpty(new Map); + * assert.isEmpty({}); + * + * @name isEmpty + * @alias empty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isEmpty = function(val, msg) { + new Assertion(val, msg, assert.isEmpty, true).to.be.empty; + }; + + /** + * ### .isNotEmpty(target) + * + * Asserts that the target contains values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isNotEmpty([1, 2]); + * assert.isNotEmpty('34'); + * assert.isNotEmpty(new Set([5, 6])); + * assert.isNotEmpty({ key: 7 }); + * + * @name isNotEmpty + * @alias notEmpty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotEmpty = function(val, msg) { + new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen') + ('isEmpty', 'empty') + ('isNotEmpty', 'notEmpty'); +}; + +},{}],7:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; + +},{}],8:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String + || this instanceof Number + || this instanceof Boolean + || typeof Symbol === 'function' && this instanceof Symbol) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; + +},{}],9:[function(require,module,exports){ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/*! + * Module variables + */ + +// Check whether `Object.setPrototypeOf` is supported +var canSetPrototype = typeof Object.setPrototypeOf === 'function'; + +// Without `Object.setPrototypeOf` support, this module will need to add properties to a function. +// However, some of functions' own props are not configurable and should be skipped. +var testFn = function() {}; +var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { + var propDesc = Object.getOwnPropertyDescriptor(testFn, name); + + // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, + // but then returns `undefined` as the property descriptor for `callee`. As a + // workaround, we perform an otherwise unnecessary type-check for `propDesc`, + // and then filter it out if it's not an object as it should be. + if (typeof propDesc !== 'object') + return true; + + return !propDesc.configurable; +}); + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### .addChainableMethod(ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + + var chainableMethodWrapper = function () { + // Setting the `ssfi` flag to `chainableMethodWrapper` causes this + // function to be the starting point for removing implementation + // frames from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then this assertion is being + // invoked from inside of another assertion. In this case, the `ssfi` + // flag has already been set by the outer assertion. + // + // Note that overwriting a chainable method merely replaces the saved + // methods in `ctx.__methods` instead of completely replacing the + // overwritten assertion. Therefore, an overwriting assertion won't + // set the `ssfi` or `lockSsfi` flags. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', chainableMethodWrapper); + } + + var result = chainableBehavior.method.apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(chainableMethodWrapper, name, true); + + // Use `Object.setPrototypeOf` if available + if (canSetPrototype) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + } + , configurable: true + }); +}; + +},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],10:[function(require,module,exports){ +var config = require('../config'); + +var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); + +/*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .addLengthGuard(fn, assertionName, isChainable) + * + * Define `length` as a getter on the given uninvoked method assertion. The + * getter acts as a guard against chaining `length` directly off of an uninvoked + * method assertion, which is a problem because it references `function`'s + * built-in `length` property instead of Chai's `length` assertion. When the + * getter catches the user making this mistake, it throws an error with a + * helpful message. + * + * There are two ways in which this mistake can be made. The first way is by + * chaining the `length` assertion directly off of an uninvoked chainable + * method. In this case, Chai suggests that the user use `lengthOf` instead. The + * second way is by chaining the `length` assertion directly off of an uninvoked + * non-chainable method. Non-chainable methods must be invoked prior to + * chaining. In this case, Chai suggests that the user consult the docs for the + * given assertion. + * + * If the `length` property of functions is unconfigurable, then return `fn` + * without modification. + * + * Note that in ES6, the function's `length` property is configurable, so once + * support for legacy environments is dropped, Chai's `length` property can + * replace the built-in function's `length` property, and this length guard will + * no longer be necessary. In the mean time, maintaining consistency across all + * environments is the priority. + * + * @param {Function} fn + * @param {String} assertionName + * @param {Boolean} isChainable + * @namespace Utils + * @name addLengthGuard + */ + +module.exports = function addLengthGuard (fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) return fn; + + Object.defineProperty(fn, 'length', { + get: function () { + if (isChainable) { + throw Error('Invalid Chai property: ' + assertionName + '.length. Due' + + ' to a compatibility issue, "length" cannot directly follow "' + + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); + } + + throw Error('Invalid Chai property: ' + assertionName + '.length. See' + + ' docs for proper usage of "' + assertionName + '".'); + } + }); + + return fn; +}; + +},{"../config":4}],11:[function(require,module,exports){ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addMethod(ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ + +module.exports = function addMethod(ctx, name, method) { + var methodWrapper = function () { + // Setting the `ssfi` flag to `methodWrapper` causes this function to be the + // starting point for removing implementation frames from the stack trace of + // a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', methodWrapper); + } + + var result = method.apply(this, arguments); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); +}; + +},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],12:[function(require,module,exports){ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addProperty(ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function addProperty(ctx, name, getter) { + getter = getter === undefined ? function () {} : getter; + + Object.defineProperty(ctx, name, + { get: function propertyGetter() { + // Setting the `ssfi` flag to `propertyGetter` causes this function to + // be the starting point for removing implementation frames from the + // stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', propertyGetter); + } + + var result = getter.call(this); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; + +},{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],13:[function(require,module,exports){ +/*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var inspect = require('./inspect'); + +/** + * ### .compareByInspect(mixed, mixed) + * + * To be used as a compareFunction with Array.prototype.sort. Compares elements + * using inspect instead of default behavior of using toString so that Symbols + * and objects with irregular/missing toString can still be sorted without a + * TypeError. + * + * @param {Mixed} first element to compare + * @param {Mixed} second element to compare + * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1 + * @name compareByInspect + * @namespace Utils + * @api public + */ + +module.exports = function compareByInspect(a, b) { + return inspect(a) < inspect(b) ? -1 : 1; +}; + +},{"./inspect":23}],14:[function(require,module,exports){ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function expectTypes(obj, types) { + var flagMsg = flag(obj, 'message'); + var ssfi = flag(obj, 'ssfi'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + var objType = type(obj).toLowerCase(); + + if (!types.some(function (expected) { return objType === expected; })) { + throw new AssertionError( + flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', + undefined, + ssfi + ); + } +}; + +},{"./flag":15,"assertion-error":33,"type-detect":38}],15:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function flag(obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; + +},{}],16:[function(require,module,exports){ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; + +},{}],17:[function(require,module,exports){ +/*! + * Chai - getEnumerableProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getEnumerableProperties(object) + * + * This allows the retrieval of enumerable property names of an object, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getEnumerableProperties + * @api public + */ + +module.exports = function getEnumerableProperties(object) { + var result = []; + for (var name in object) { + result.push(name); + } + return result; +}; + +},{}],18:[function(require,module,exports){ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , inspect = require('./inspect') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function getMessage(obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; + +},{"./flag":15,"./getActual":16,"./inspect":23,"./objDisplay":26}],19:[function(require,module,exports){ +/*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/** + * ### .getOwnEnumerableProperties(object) + * + * This allows the retrieval of directly-owned enumerable property names and + * symbols of an object. This function is necessary because Object.keys only + * returns enumerable property names, not enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerableProperties + * @api public + */ + +module.exports = function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); +}; + +},{"./getOwnEnumerablePropertySymbols":20}],20:[function(require,module,exports){ +/*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getOwnEnumerablePropertySymbols(object) + * + * This allows the retrieval of directly-owned enumerable property symbols of an + * object. This function is necessary because Object.getOwnPropertySymbols + * returns both enumerable and non-enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerablePropertySymbols + * @api public + */ + +module.exports = function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== 'function') return []; + + return Object.getOwnPropertySymbols(obj).filter(function (sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); +}; + +},{}],21:[function(require,module,exports){ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; + +},{}],22:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Dependencies that are used for multiple exports are required here only once + */ + +var pathval = require('pathval'); + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path info + */ + +exports.getPathInfo = pathval.getPathInfo; + +/*! + * Check if a property exists + */ + +exports.hasProperty = pathval.hasProperty; + +/*! + * Function name + */ + +exports.getName = require('get-func-name'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); + +/*! + * Compare by inspect method + */ + +exports.compareByInspect = require('./compareByInspect'); + +/*! + * Get own enumerable property symbols method + */ + +exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/*! + * Get own enumerable properties method + */ + +exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties'); + +/*! + * Checks error against a given set of criteria + */ + +exports.checkError = require('check-error'); + +/*! + * Proxify util + */ + +exports.proxify = require('./proxify'); + +/*! + * addLengthGuard util + */ + +exports.addLengthGuard = require('./addLengthGuard'); + +/*! + * isProxyEnabled helper + */ + +exports.isProxyEnabled = require('./isProxyEnabled'); + +/*! + * isNaN method + */ + +exports.isNaN = require('./isNaN'); + +},{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":18,"./getOwnEnumerableProperties":19,"./getOwnEnumerablePropertySymbols":20,"./inspect":23,"./isNaN":24,"./isProxyEnabled":25,"./objDisplay":26,"./overwriteChainableMethod":27,"./overwriteMethod":28,"./overwriteProperty":29,"./proxify":30,"./test":31,"./transferFlags":32,"check-error":34,"deep-eql":35,"get-func-name":36,"pathval":37,"type-detect":38}],23:[function(require,module,exports){ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('get-func-name'); +var getProperties = require('./getProperties'); +var getEnumerableProperties = require('./getEnumerableProperties'); +var config = require('../config'); + +module.exports = inspect; + +/** + * ### .inspect(obj, [showHidden], [depth], [colors]) + * + * Echoes the value of a value. Tries to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. Default is false. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var ctx = { + showHidden: showHidden, + seen: [], + stylize: function (str) { return str; } + }; + return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); +} + +// Returns true if object is a DOM element. +var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + 'nodeType' in object && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } +}; + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (typeof ret !== 'string') { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // If this is a DOM element, try to get the outer HTML. + if (isDOMElement(value)) { + if ('outerHTML' in value) { + return value.outerHTML; + // This value does not have an outerHTML attribute, + // it could still be an XML element + } else { + // Attempt to serialize it + try { + if (document.xmlVersion) { + var xmlSerializer = new XMLSerializer(); + return xmlSerializer.serializeToString(value); + } else { + // Firefox 11- do not support outerHTML + // It does, however, support innerHTML + // Use the following to render the element + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + + container.appendChild(value.cloneNode(false)); + var html = container.innerHTML + .replace('><', '>' + value.innerHTML + '<'); + container.innerHTML = ''; + return html; + } + } catch (err) { + // This could be a non-native DOM implementation, + // continue with the normal flow: + // printing the element as if it is an object. + } + } + } + + // Look up the keys of the object. + var visibleKeys = getEnumerableProperties(value); + var keys = ctx.showHidden ? getProperties(value) : visibleKeys; + + var name, nameSuffix; + + // Some type of object without properties can be shortcutted. + // In IE, errors have a single `stack` property, or if they are vanilla `Error`, + // a `stack` plus `description` property; ignore those for consistency. + if (keys.length === 0 || (isError(value) && ( + (keys.length === 1 && keys[0] === 'stack') || + (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') + ))) { + if (typeof value === 'function') { + name = getName(value); + nameSuffix = name ? ': ' + name : ''; + return ctx.stylize('[Function' + nameSuffix + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '' + , array = false + , typedArray = false + , braces = ['{', '}']; + + if (isTypedArray(value)) { + typedArray = true; + braces = ['[', ']']; + } + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + name = getName(value); + nameSuffix = name ? ': ' + name : ''; + base = ' [Function' + nameSuffix + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + return formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else if (typedArray) { + return formatTypedArray(value); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + switch (typeof value) { + case 'undefined': + return ctx.stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + + case 'number': + if (value === 0 && (1/value) === -Infinity) { + return ctx.stylize('-0', 'number'); + } + return ctx.stylize('' + value, 'number'); + + case 'boolean': + return ctx.stylize('' + value, 'boolean'); + + case 'symbol': + return ctx.stylize(value.toString(), 'symbol'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return ctx.stylize('null', 'null'); + } +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (Object.prototype.hasOwnProperty.call(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + +function formatTypedArray(value) { + var str = '[ '; + + for (var i = 0; i < value.length; ++i) { + if (str.length >= config.truncateThreshold - 7) { + str += '...'; + break; + } + str += value[i] + ', '; + } + str += ' ]'; + + // Removing trailing `, ` if the array was not truncated + if (str.indexOf(', ]') !== -1) { + str = str.replace(', ]', ' ]'); + } + + return str; +} + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name; + var propDescriptor = Object.getOwnPropertyDescriptor(value, key); + var str; + + if (propDescriptor) { + if (propDescriptor.get) { + if (propDescriptor.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (propDescriptor.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + } + if (visibleKeys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = formatValue(ctx, value[key], null); + } else { + str = formatValue(ctx, value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function isTypedArray(ar) { + // Unfortunately there's no way to check if an object is a TypedArray + // We have to check if it's one of these types + return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar))); +} + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && objectToString(ar) === '[object Array]'); +} + +function isRegExp(re) { + return typeof re === 'object' && objectToString(re) === '[object RegExp]'; +} + +function isDate(d) { + return typeof d === 'object' && objectToString(d) === '[object Date]'; +} + +function isError(e) { + return typeof e === 'object' && objectToString(e) === '[object Error]'; +} + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +},{"../config":4,"./getEnumerableProperties":17,"./getProperties":21,"get-func-name":36}],24:[function(require,module,exports){ +/*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani + * MIT Licensed + */ + +/** + * ### .isNaN(value) + * + * Checks if the given value is NaN or not. + * + * utils.isNaN(NaN); // true + * + * @param {Value} The value which has to be checked if it is NaN + * @name isNaN + * @api private + */ + +function isNaN(value) { + // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number + // section's NOTE. + return value !== value; +} + +// If ECMAScript 6's Number.isNaN is present, prefer that. +module.exports = Number.isNaN || isNaN; + +},{}],25:[function(require,module,exports){ +var config = require('../config'); + +/*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .isProxyEnabled() + * + * Helper function to check if Chai's proxy protection feature is enabled. If + * proxies are unsupported or disabled via the user's Chai config, then return + * false. Otherwise, return true. + * + * @namespace Utils + * @name isProxyEnabled + */ + +module.exports = function isProxyEnabled() { + return config.useProxy && + typeof Proxy !== 'undefined' && + typeof Reflect !== 'undefined'; +}; + +},{"../config":4}],26:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay(object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function objDisplay(obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; + +},{"../config":4,"./inspect":23}],27:[function(require,module,exports){ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) + * + * Overwites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.lengthOf(3); + * expect(myFoo).to.have.lengthOf.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { + var result = chainingBehavior(_chainingBehavior).call(this); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function overwritingChainableMethodWrapper() { + var result = method(_method).apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; +}; + +},{"../../chai":2,"./transferFlags":32}],28:[function(require,module,exports){ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteMethod(ctx, name, fn) + * + * Overwites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function overwriteMethod(ctx, name, method) { + var _method = ctx[name] + , _super = function () { + throw new Error(name + ' is not a function'); + }; + + if (_method && 'function' === typeof _method) + _super = _method; + + var overwritingMethodWrapper = function () { + // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this + // function to be the starting point for removing implementation frames from + // the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingMethodWrapper); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion + // from changing the `ssfi` flag. By this point, the `ssfi` flag is already + // set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = method(_super).apply(this, arguments); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); +}; + +},{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],29:[function(require,module,exports){ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteProperty(ctx, name, fn) + * + * Overwites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function overwriteProperty(ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function overwritingPropertyGetter() { + // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this + // function to be the starting point for removing implementation frames + // from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingPropertyGetter); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten + // assertion from changing the `ssfi` flag. By this point, the `ssfi` + // flag is already set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = getter(_super).call(this); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; + +},{"../../chai":2,"./flag":15,"./isProxyEnabled":25,"./transferFlags":32}],30:[function(require,module,exports){ +var config = require('../config'); +var flag = require('./flag'); +var getProperties = require('./getProperties'); +var isProxyEnabled = require('./isProxyEnabled'); + +/*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .proxify(object) + * + * Return a proxy of given object that throws an error when a non-existent + * property is read. By default, the root cause is assumed to be a misspelled + * property, and thus an attempt is made to offer a reasonable suggestion from + * the list of existing properties. However, if a nonChainableMethodName is + * provided, then the root cause is instead a failure to invoke a non-chainable + * method prior to reading the non-existent property. + * + * If proxies are unsupported or disabled via the user's Chai config, then + * return object without modification. + * + * @param {Object} obj + * @param {String} nonChainableMethodName + * @namespace Utils + * @name proxify + */ + +var builtins = ['__flags', '__methods', '_obj', 'assert']; + +module.exports = function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) return obj; + + return new Proxy(obj, { + get: function proxyGetter(target, property) { + // This check is here because we should not throw errors on Symbol properties + // such as `Symbol.toStringTag`. + // The values for which an error should be thrown can be configured using + // the `config.proxyExcludedKeys` setting. + if (typeof property === 'string' && + config.proxyExcludedKeys.indexOf(property) === -1 && + !Reflect.has(target, property)) { + // Special message for invalid property access of non-chainable methods. + if (nonChainableMethodName) { + throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' + + property + '. See docs for proper usage of "' + + nonChainableMethodName + '".'); + } + + var orderedProperties = getProperties(target).filter(function(property) { + return !Object.prototype.hasOwnProperty(property) && + builtins.indexOf(property) === -1; + }).sort(function(a, b) { + return stringDistance(property, a) - stringDistance(property, b); + }); + + if (orderedProperties.length && + stringDistance(orderedProperties[0], property) < 4) { + // If the property is reasonably close to an existing Chai property, + // suggest that property to the user. + throw Error('Invalid Chai property: ' + property + + '. Did you mean "' + orderedProperties[0] + '"?'); + } else { + throw Error('Invalid Chai property: ' + property); + } + } + + // Use this proxy getter as the starting point for removing implementation + // frames from the stack trace of a failed assertion. For property + // assertions, this prevents the proxy getter from showing up in the stack + // trace since it's invoked before the property getter. For method and + // chainable method assertions, this flag will end up getting changed to + // the method wrapper, which is good since this frame will no longer be in + // the stack once the method is invoked. Note that Chai builtin assertion + // properties such as `__flags` are skipped since this is only meant to + // capture the starting point of an assertion. This step is also skipped + // if the `lockSsfi` flag is set, thus indicating that this assertion is + // being called from within another assertion. In that case, the `ssfi` + // flag is already set to the outer assertion's starting point. + if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { + flag(target, 'ssfi', proxyGetter); + } + + return Reflect.get(target, property); + } + }); +}; + +/** + * # stringDistance(strA, strB) + * Return the Levenshtein distance between two strings. + * @param {string} strA + * @param {string} strB + * @return {number} the string distance between strA and strB + * @api private + */ + +function stringDistance(strA, strB, memo) { + if (!memo) { + // `memo` is a two-dimensional array containing a cache of distances + // memo[i][j] is the distance between strA.slice(0, i) and + // strB.slice(0, j). + memo = []; + for (var i = 0; i <= strA.length; i++) { + memo[i] = []; + } + } + + if (!memo[strA.length] || !memo[strA.length][strB.length]) { + if (strA.length === 0 || strB.length === 0) { + memo[strA.length][strB.length] = Math.max(strA.length, strB.length); + } else { + memo[strA.length][strB.length] = Math.min( + stringDistance(strA.slice(0, -1), strB, memo) + 1, + stringDistance(strA, strB.slice(0, -1), memo) + 1, + stringDistance(strA.slice(0, -1), strB.slice(0, -1), memo) + + (strA.slice(-1) === strB.slice(-1) ? 0 : 1) + ); + } + } + + return memo[strA.length][strB.length]; +} + +},{"../config":4,"./flag":15,"./getProperties":21,"./isProxyEnabled":25}],31:[function(require,module,exports){ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag'); + +/** + * ### .test(object, expression) + * + * Test and object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function test(obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; + +},{"./flag":15}],32:[function(require,module,exports){ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, `lockSsfi`, + * and `message`) will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAsseriton = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function transferFlags(assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; + +},{}],33:[function(require,module,exports){ +/*! + * assertion-error + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Return a function that will copy properties from + * one object to another excluding any originally + * listed. Returned function will create a new `{}`. + * + * @param {String} excluded properties ... + * @return {Function} + */ + +function exclude () { + var excludes = [].slice.call(arguments); + + function excludeProps (res, obj) { + Object.keys(obj).forEach(function (key) { + if (!~excludes.indexOf(key)) res[key] = obj[key]; + }); + } + + return function extendExclude () { + var args = [].slice.call(arguments) + , i = 0 + , res = {}; + + for (; i < args.length; i++) { + excludeProps(res, args[i]); + } + + return res; + }; +}; + +/*! + * Primary Exports + */ + +module.exports = AssertionError; + +/** + * ### AssertionError + * + * An extension of the JavaScript `Error` constructor for + * assertion and validation scenarios. + * + * @param {String} message + * @param {Object} properties to include (optional) + * @param {callee} start stack function (optional) + */ + +function AssertionError (message, _props, ssf) { + var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') + , props = extend(_props || {}); + + // default values + this.message = message || 'Unspecified AssertionError'; + this.showDiff = false; + + // copy from properties + for (var key in props) { + this[key] = props[key]; + } + + // capture stack trace + ssf = ssf || arguments.callee; + if (ssf && Error.captureStackTrace) { + Error.captureStackTrace(this, ssf); + } else { + try { + throw new Error(); + } catch(e) { + this.stack = e.stack; + } + } +} + +/*! + * Inherit from Error.prototype + */ + +AssertionError.prototype = Object.create(Error.prototype); + +/*! + * Statically set name + */ + +AssertionError.prototype.name = 'AssertionError'; + +/*! + * Ensure correct constructor + */ + +AssertionError.prototype.constructor = AssertionError; + +/** + * Allow errors to be converted to JSON for static transfer. + * + * @param {Boolean} include stack (default: `true`) + * @return {Object} object that can be `JSON.stringify` + */ + +AssertionError.prototype.toJSON = function (stack) { + var extend = exclude('constructor', 'toJSON', 'stack') + , props = extend({ name: this.name }, this); + + // include stack if exists and not turned off + if (false !== stack && this.stack) { + props.stack = this.stack; + } + + return props; +}; + +},{}],34:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - checkError utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .checkError + * + * Checks that an error conforms to a given set of criteria and/or retrieves information about it. + * + * @api public + */ + +/** + * ### .compatibleInstance(thrown, errorLike) + * + * Checks if two instances are compatible (strict equal). + * Returns false if errorLike is not an instance of Error, because instances + * can only be compatible if they're both error instances. + * + * @name compatibleInstance + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleInstance(thrown, errorLike) { + return errorLike instanceof Error && thrown === errorLike; +} + +/** + * ### .compatibleConstructor(thrown, errorLike) + * + * Checks if two constructors are compatible. + * This function can receive either an error constructor or + * an error instance as the `errorLike` argument. + * Constructors are compatible if they're the same or if one is + * an instance of another. + * + * @name compatibleConstructor + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleConstructor(thrown, errorLike) { + if (errorLike instanceof Error) { + // If `errorLike` is an instance of any error we compare their constructors + return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; + } else if (errorLike.prototype instanceof Error || errorLike === Error) { + // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly + return thrown.constructor === errorLike || thrown instanceof errorLike; + } + + return false; +} + +/** + * ### .compatibleMessage(thrown, errMatcher) + * + * Checks if an error's message is compatible with a matcher (String or RegExp). + * If the message contains the String or passes the RegExp test, + * it is considered compatible. + * + * @name compatibleMessage + * @param {Error} thrown error + * @param {String|RegExp} errMatcher to look for into the message + * @namespace Utils + * @api public + */ + +function compatibleMessage(thrown, errMatcher) { + var comparisonString = typeof thrown === 'string' ? thrown : thrown.message; + if (errMatcher instanceof RegExp) { + return errMatcher.test(comparisonString); + } else if (typeof errMatcher === 'string') { + return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers + } + + return false; +} + +/** + * ### .getFunctionName(constructorFn) + * + * Returns the name of a function. + * This also includes a polyfill function if `constructorFn.name` is not defined. + * + * @name getFunctionName + * @param {Function} constructorFn + * @namespace Utils + * @api private + */ + +var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/; +function getFunctionName(constructorFn) { + var name = ''; + if (typeof constructorFn.name === 'undefined') { + // Here we run a polyfill if constructorFn.name is not defined + var match = String(constructorFn).match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + name = constructorFn.name; + } + + return name; +} + +/** + * ### .getConstructorName(errorLike) + * + * Gets the constructor name for an Error instance or constructor itself. + * + * @name getConstructorName + * @param {Error|ErrorConstructor} errorLike + * @namespace Utils + * @api public + */ + +function getConstructorName(errorLike) { + var constructorName = errorLike; + if (errorLike instanceof Error) { + constructorName = getFunctionName(errorLike.constructor); + } else if (typeof errorLike === 'function') { + // If `err` is not an instance of Error it is an error constructor itself or another function. + // If we've got a common function we get its name, otherwise we may need to create a new instance + // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more. + constructorName = getFunctionName(errorLike).trim() || + getFunctionName(new errorLike()); // eslint-disable-line new-cap + } + + return constructorName; +} + +/** + * ### .getMessage(errorLike) + * + * Gets the error message from an error. + * If `err` is a String itself, we return it. + * If the error has no message, we return an empty string. + * + * @name getMessage + * @param {Error|String} errorLike + * @namespace Utils + * @api public + */ + +function getMessage(errorLike) { + var msg = ''; + if (errorLike && errorLike.message) { + msg = errorLike.message; + } else if (typeof errorLike === 'string') { + msg = errorLike; + } + + return msg; +} + +module.exports = { + compatibleInstance: compatibleInstance, + compatibleConstructor: compatibleConstructor, + compatibleMessage: compatibleMessage, + getMessage: getMessage, + getConstructorName: getConstructorName, +}; + +},{}],35:[function(require,module,exports){ +'use strict'; +/* globals Symbol: false, Uint8Array: false, WeakMap: false */ +/*! + * deep-eql + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +var type = require('type-detect'); +function FakeMap() { + this._key = 'chai/deep-eql__' + Math.random() + Date.now(); +} + +FakeMap.prototype = { + get: function getMap(key) { + return key[this._key]; + }, + set: function setMap(key, value) { + if (!Object.isFrozen(key)) { + Object.defineProperty(key, this._key, { + value: value, + configurable: true, + }); + } + }, +}; + +var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap; +/*! + * Check to see if the MemoizeMap has recorded a result of the two operands + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @returns {Boolean|null} result +*/ +function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return null; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + var result = leftHandMap.get(rightHandOperand); + if (typeof result === 'boolean') { + return result; + } + } + return null; +} + +/*! + * Set the result of the equality into the MemoizeMap + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @param {Boolean} result +*/ +function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + leftHandMap.set(rightHandOperand, result); + } else { + leftHandMap = new MemoizeMap(); + leftHandMap.set(rightHandOperand, result); + memoizeMap.set(leftHandOperand, leftHandMap); + } +} + +/*! + * Primary Export + */ + +module.exports = deepEqual; +module.exports.MemoizeMap = MemoizeMap; + +/** + * Assert deeply nested sameValue equality between two objects of any type. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match + */ +function deepEqual(leftHandOperand, rightHandOperand, options) { + // If we have a comparator, we can't assume anything; so bail to its check first. + if (options && options.comparator) { + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + + // Deeper comparisons are pushed through to a larger function + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); +} + +/** + * Many comparisons can be canceled out early via simple equality or primitive checks. + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @return {Boolean|null} equal match + */ +function simpleEqual(leftHandOperand, rightHandOperand) { + // Equal references (except for Numbers) can be returned early + if (leftHandOperand === rightHandOperand) { + // Handle +-0 cases + return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; + } + + // handle NaN cases + if ( + leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare + rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare + ) { + return true; + } + + // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, + // strings, and undefined, can be compared by reference. + if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + // Easy out b/c it would have passed the first equality check + return false; + } + return null; +} + +/*! + * The main logic of the `deepEqual` function. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match +*/ +function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { + options = options || {}; + options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); + var comparator = options && options.comparator; + + // Check if a memoized result exists. + var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); + if (memoizeResultLeft !== null) { + return memoizeResultLeft; + } + var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); + if (memoizeResultRight !== null) { + return memoizeResultRight; + } + + // If a comparator is present, use it. + if (comparator) { + var comparatorResult = comparator(leftHandOperand, rightHandOperand); + // Comparators may return null, in which case we want to go back to default behavior. + if (comparatorResult === false || comparatorResult === true) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); + return comparatorResult; + } + // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide + // what to do, we need to make sure to return the basic tests first before we move on. + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + // Don't memoize this, it takes longer to set/retrieve than to just compare. + return simpleResult; + } + } + + var leftHandType = type(leftHandOperand); + if (leftHandType !== type(rightHandOperand)) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); + return false; + } + + // Temporarily set the operands in the memoize object to prevent blowing the stack + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); + + var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); + return result; +} + +function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { + switch (leftHandType) { + case 'String': + case 'Number': + case 'Boolean': + case 'Date': + // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values + return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); + case 'Promise': + case 'Symbol': + case 'function': + case 'WeakMap': + case 'WeakSet': + case 'Error': + return leftHandOperand === rightHandOperand; + case 'Arguments': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'Array': + return iterableEqual(leftHandOperand, rightHandOperand, options); + case 'RegExp': + return regexpEqual(leftHandOperand, rightHandOperand); + case 'Generator': + return generatorEqual(leftHandOperand, rightHandOperand, options); + case 'DataView': + return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); + case 'ArrayBuffer': + return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); + case 'Set': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Map': + return entriesEqual(leftHandOperand, rightHandOperand, options); + default: + return objectEqual(leftHandOperand, rightHandOperand, options); + } +} + +/*! + * Compare two Regular Expressions for equality. + * + * @param {RegExp} leftHandOperand + * @param {RegExp} rightHandOperand + * @return {Boolean} result + */ + +function regexpEqual(leftHandOperand, rightHandOperand) { + return leftHandOperand.toString() === rightHandOperand.toString(); +} + +/*! + * Compare two Sets/Maps for equality. Faster than other equality functions. + * + * @param {Set} leftHandOperand + * @param {Set} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function entriesEqual(leftHandOperand, rightHandOperand, options) { + // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach + if (leftHandOperand.size !== rightHandOperand.size) { + return false; + } + if (leftHandOperand.size === 0) { + return true; + } + var leftHandItems = []; + var rightHandItems = []; + leftHandOperand.forEach(function gatherEntries(key, value) { + leftHandItems.push([ key, value ]); + }); + rightHandOperand.forEach(function gatherEntries(key, value) { + rightHandItems.push([ key, value ]); + }); + return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); +} + +/*! + * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function iterableEqual(leftHandOperand, rightHandOperand, options) { + var length = leftHandOperand.length; + if (length !== rightHandOperand.length) { + return false; + } + if (length === 0) { + return true; + } + var index = -1; + while (++index < length) { + if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { + return false; + } + } + return true; +} + +/*! + * Simple equality for generator objects such as those returned by generator functions. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function generatorEqual(leftHandOperand, rightHandOperand, options) { + return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); +} + +/*! + * Determine if the given object has an @@iterator function. + * + * @param {Object} target + * @return {Boolean} `true` if the object has an @@iterator function. + */ +function hasIteratorFunction(target) { + return typeof Symbol !== 'undefined' && + typeof target === 'object' && + typeof Symbol.iterator !== 'undefined' && + typeof target[Symbol.iterator] === 'function'; +} + +/*! + * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. + * This will consume the iterator - which could have side effects depending on the @@iterator implementation. + * + * @param {Object} target + * @returns {Array} an array of entries from the @@iterator function + */ +function getIteratorEntries(target) { + if (hasIteratorFunction(target)) { + try { + return getGeneratorEntries(target[Symbol.iterator]()); + } catch (iteratorError) { + return []; + } + } + return []; +} + +/*! + * Gets all entries from a Generator. This will consume the generator - which could have side effects. + * + * @param {Generator} target + * @returns {Array} an array of entries from the Generator. + */ +function getGeneratorEntries(generator) { + var generatorResult = generator.next(); + var accumulator = [ generatorResult.value ]; + while (generatorResult.done === false) { + generatorResult = generator.next(); + accumulator.push(generatorResult.value); + } + return accumulator; +} + +/*! + * Gets all own and inherited enumerable keys from a target. + * + * @param {Object} target + * @returns {Array} an array of own and inherited enumerable keys from the target. + */ +function getEnumerableKeys(target) { + var keys = []; + for (var key in target) { + keys.push(key); + } + return keys; +} + +/*! + * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of + * each key. If any value of the given key is not equal, the function will return false (early). + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function keysEqual(leftHandOperand, rightHandOperand, keys, options) { + var length = keys.length; + if (length === 0) { + return true; + } + for (var i = 0; i < length; i += 1) { + if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { + return false; + } + } + return true; +} + +/*! + * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` + * for each enumerable key in the object. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function objectEqual(leftHandOperand, rightHandOperand, options) { + var leftHandKeys = getEnumerableKeys(leftHandOperand); + var rightHandKeys = getEnumerableKeys(rightHandOperand); + if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { + leftHandKeys.sort(); + rightHandKeys.sort(); + if (iterableEqual(leftHandKeys, rightHandKeys) === false) { + return false; + } + return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); + } + + var leftHandEntries = getIteratorEntries(leftHandOperand); + var rightHandEntries = getIteratorEntries(rightHandOperand); + if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { + leftHandEntries.sort(); + rightHandEntries.sort(); + return iterableEqual(leftHandEntries, rightHandEntries, options); + } + + if (leftHandKeys.length === 0 && + leftHandEntries.length === 0 && + rightHandKeys.length === 0 && + rightHandEntries.length === 0) { + return true; + } + + return false; +} + +/*! + * Returns true if the argument is a primitive. + * + * This intentionally returns true for all objects that can be compared by reference, + * including functions and symbols. + * + * @param {Mixed} value + * @return {Boolean} result + */ +function isPrimitive(value) { + return value === null || typeof value !== 'object'; +} + +},{"type-detect":38}],36:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - getFuncName utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getFuncName(constructorFn) + * + * Returns the name of a function. + * When a non-function instance is passed, returns `null`. + * This also includes a polyfill function if `aFunc.name` is not defined. + * + * @name getFuncName + * @param {Function} funct + * @namespace Utils + * @api public + */ + +var toString = Function.prototype.toString; +var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; +function getFuncName(aFunc) { + if (typeof aFunc !== 'function') { + return null; + } + + var name = ''; + if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { + // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined + var match = toString.call(aFunc).match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + // If we've got a `name` property we just use it + name = aFunc.name; + } + + return name; +} + +module.exports = getFuncName; + +},{}],37:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - pathval utility + * Copyright(c) 2012-2014 Jake Luer + * @see https://github.com/logicalparadox/filtr + * MIT Licensed + */ + +/** + * ### .hasProperty(object, name) + * + * This allows checking whether an object has own + * or inherited from prototype chain named property. + * + * Basically does the same thing as the `in` + * operator but works properly with null/undefined values + * and other primitives. + * + * var obj = { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * + * The following would be the results. + * + * hasProperty(obj, 'str'); // true + * hasProperty(obj, 'constructor'); // true + * hasProperty(obj, 'bar'); // false + * + * hasProperty(obj.str, 'length'); // true + * hasProperty(obj.str, 1); // true + * hasProperty(obj.str, 5); // false + * + * hasProperty(obj.arr, 'length'); // true + * hasProperty(obj.arr, 2); // true + * hasProperty(obj.arr, 3); // false + * + * @param {Object} object + * @param {String|Symbol} name + * @returns {Boolean} whether it exists + * @namespace Utils + * @name hasProperty + * @api public + */ + +function hasProperty(obj, name) { + if (typeof obj === 'undefined' || obj === null) { + return false; + } + + // The `in` operator does not work with primitives. + return name in Object(obj); +} + +/* ! + * ## parsePath(path) + * + * Helper function used to parse string object + * paths. Use in conjunction with `internalGetPathValue`. + * + * var parsed = parsePath('myobject.property.subprop'); + * + * ### Paths: + * + * * Can be infinitely deep and nested. + * * Arrays are also valid using the formal `myobject.document[3].property`. + * * Literal dots and brackets (not delimiter) must be backslash-escaped. + * + * @param {String} path + * @returns {Object} parsed + * @api private + */ + +function parsePath(path) { + var str = path.replace(/([^\\])\[/g, '$1.['); + var parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map(function mapMatches(value) { + var regexp = /^\[(\d+)\]$/; + var mArr = regexp.exec(value); + var parsed = null; + if (mArr) { + parsed = { i: parseFloat(mArr[1]) }; + } else { + parsed = { p: value.replace(/\\([.\[\]])/g, '$1') }; + } + + return parsed; + }); +} + +/* ! + * ## internalGetPathValue(obj, parsed[, pathDepth]) + * + * Helper companion function for `.parsePath` that returns + * the value located at the parsed address. + * + * var value = getPathValue(obj, parsed); + * + * @param {Object} object to search against + * @param {Object} parsed definition from `parsePath`. + * @param {Number} depth (nesting level) of the property we want to retrieve + * @returns {Object|Undefined} value + * @api private + */ + +function internalGetPathValue(obj, parsed, pathDepth) { + var temporaryValue = obj; + var res = null; + pathDepth = (typeof pathDepth === 'undefined' ? parsed.length : pathDepth); + + for (var i = 0; i < pathDepth; i++) { + var part = parsed[i]; + if (temporaryValue) { + if (typeof part.p === 'undefined') { + temporaryValue = temporaryValue[part.i]; + } else { + temporaryValue = temporaryValue[part.p]; + } + + if (i === (pathDepth - 1)) { + res = temporaryValue; + } + } + } + + return res; +} + +/* ! + * ## internalSetPathValue(obj, value, parsed) + * + * Companion function for `parsePath` that sets + * the value located at a parsed address. + * + * internalSetPathValue(obj, 'value', parsed); + * + * @param {Object} object to search and define on + * @param {*} value to use upon set + * @param {Object} parsed definition from `parsePath` + * @api private + */ + +function internalSetPathValue(obj, val, parsed) { + var tempObj = obj; + var pathDepth = parsed.length; + var part = null; + // Here we iterate through every part of the path + for (var i = 0; i < pathDepth; i++) { + var propName = null; + var propVal = null; + part = parsed[i]; + + // If it's the last part of the path, we set the 'propName' value with the property name + if (i === (pathDepth - 1)) { + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Now we set the property with the name held by 'propName' on object with the desired val + tempObj[propName] = val; + } else if (typeof part.p !== 'undefined' && tempObj[part.p]) { + tempObj = tempObj[part.p]; + } else if (typeof part.i !== 'undefined' && tempObj[part.i]) { + tempObj = tempObj[part.i]; + } else { + // If the obj doesn't have the property we create one with that name to define it + var next = parsed[i + 1]; + // Here we set the name of the property which will be defined + propName = typeof part.p === 'undefined' ? part.i : part.p; + // Here we decide if this property will be an array or a new object + propVal = typeof next.p === 'undefined' ? [] : {}; + tempObj[propName] = propVal; + tempObj = tempObj[propName]; + } + } +} + +/** + * ### .getPathInfo(object, path) + * + * This allows the retrieval of property info in an + * object given a string path. + * + * The path info consists of an object with the + * following properties: + * + * * parent - The parent object of the property referenced by `path` + * * name - The name of the final property, a number if it was an array indexer + * * value - The value of the property, if it exists, otherwise `undefined` + * * exists - Whether the property exists or not + * + * @param {Object} object + * @param {String} path + * @returns {Object} info + * @namespace Utils + * @name getPathInfo + * @api public + */ + +function getPathInfo(obj, path) { + var parsed = parsePath(path); + var last = parsed[parsed.length - 1]; + var info = { + parent: parsed.length > 1 ? internalGetPathValue(obj, parsed, parsed.length - 1) : obj, + name: last.p || last.i, + value: internalGetPathValue(obj, parsed), + }; + info.exists = hasProperty(info.parent, info.name); + + return info; +} + +/** + * ### .getPathValue(object, path) + * + * This allows the retrieval of values in an + * object given a string path. + * + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * } + * + * The following would be the results. + * + * getPathValue(obj, 'prop1.str'); // Hello + * getPathValue(obj, 'prop1.att[2]'); // b + * getPathValue(obj, 'prop2.arr[0].nested'); // Universe + * + * @param {Object} object + * @param {String} path + * @returns {Object} value or `undefined` + * @namespace Utils + * @name getPathValue + * @api public + */ + +function getPathValue(obj, path) { + var info = getPathInfo(obj, path); + return info.value; +} + +/** + * ### .setPathValue(object, path, value) + * + * Define the value in an object at a given string path. + * + * ```js + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * }; + * ``` + * + * The following would be acceptable. + * + * ```js + * var properties = require('tea-properties'); + * properties.set(obj, 'prop1.str', 'Hello Universe!'); + * properties.set(obj, 'prop1.arr[2]', 'B'); + * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' }); + * ``` + * + * @param {Object} object + * @param {String} path + * @param {Mixed} value + * @api private + */ + +function setPathValue(obj, path, val) { + var parsed = parsePath(path); + internalSetPathValue(obj, val, parsed); + return obj; +} + +module.exports = { + hasProperty: hasProperty, + getPathInfo: getPathInfo, + getPathValue: getPathValue, + setPathValue: setPathValue, +}; + +},{}],38:[function(require,module,exports){ +'use strict'; + +/* ! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ +var promiseExists = typeof Promise === 'function'; +var globalObject = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : self; // eslint-disable-line +var isDom = 'location' in globalObject && 'document' in globalObject; +var symbolExists = typeof Symbol !== 'undefined'; +var mapExists = typeof Map !== 'undefined'; +var setExists = typeof Set !== 'undefined'; +var weakMapExists = typeof WeakMap !== 'undefined'; +var weakSetExists = typeof WeakSet !== 'undefined'; +var dataViewExists = typeof DataView !== 'undefined'; +var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; +var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; +var setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; +var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; +var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); +var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); +var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; +var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); +var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; +var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); +var toStringLeftSliceLength = 8; +var toStringRightSliceLength = -1; +/** + * ### typeOf (obj) + * + * Uses `Object.prototype.toString` to determine the type of an object, + * normalising behaviour across engine versions & well optimised. + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ +module.exports = function typeDetect(obj) { + /* ! Speed optimisation + * Pre: + * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) + * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) + * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) + * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) + * function x 2,556,769 ops/sec ±1.73% (77 runs sampled) + * Post: + * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) + * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) + * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) + * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) + * function x 31,296,870 ops/sec ±0.96% (83 runs sampled) + */ + var typeofObj = typeof obj; + if (typeofObj !== 'object') { + return typeofObj; + } + + /* ! Speed optimisation + * Pre: + * null x 28,645,765 ops/sec ±1.17% (82 runs sampled) + * Post: + * null x 36,428,962 ops/sec ±1.37% (84 runs sampled) + */ + if (obj === null) { + return 'null'; + } + + /* ! Spec Conformance + * Test: `Object.prototype.toString.call(window)`` + * - Node === "[object global]" + * - Chrome === "[object global]" + * - Firefox === "[object Window]" + * - PhantomJS === "[object Window]" + * - Safari === "[object Window]" + * - IE 11 === "[object Window]" + * - IE Edge === "[object Window]" + * Test: `Object.prototype.toString.call(this)`` + * - Chrome Worker === "[object global]" + * - Firefox Worker === "[object DedicatedWorkerGlobalScope]" + * - Safari Worker === "[object DedicatedWorkerGlobalScope]" + * - IE 11 Worker === "[object WorkerGlobalScope]" + * - IE Edge Worker === "[object WorkerGlobalScope]" + */ + if (obj === globalObject) { + return 'global'; + } + + /* ! Speed optimisation + * Pre: + * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) + * Post: + * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) + */ + if ( + Array.isArray(obj) && + (symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) + ) { + return 'Array'; + } + + if (isDom) { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/browsers.html#location) + * WhatWG HTML$7.7.3 - The `Location` interface + * Test: `Object.prototype.toString.call(window.location)`` + * - IE <=11 === "[object Object]" + * - IE Edge <=13 === "[object Object]" + */ + if (obj === globalObject.location) { + return 'Location'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#document) + * WhatWG HTML$3.1.1 - The `Document` object + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * WhatWG HTML states: + * > For historical reasons, Window objects must also have a + * > writable, configurable, non-enumerable property named + * > HTMLDocument whose value is the Document interface object. + * Test: `Object.prototype.toString.call(document)`` + * - Chrome === "[object HTMLDocument]" + * - Firefox === "[object HTMLDocument]" + * - Safari === "[object HTMLDocument]" + * - IE <=10 === "[object Document]" + * - IE 11 === "[object HTMLDocument]" + * - IE Edge <=13 === "[object HTMLDocument]" + */ + if (obj === globalObject.document) { + return 'Document'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray + * Test: `Object.prototype.toString.call(navigator.mimeTypes)`` + * - IE <=10 === "[object MSMimeTypesCollection]" + */ + if (obj === (globalObject.navigator || {}).mimeTypes) { + return 'MimeTypeArray'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray + * Test: `Object.prototype.toString.call(navigator.plugins)`` + * - IE <=10 === "[object MSPluginsCollection]" + */ + if (obj === (globalObject.navigator || {}).plugins) { + return 'PluginArray'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` + * Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` + * - IE <=10 === "[object HTMLBlockElement]" + */ + if (obj instanceof HTMLElement && obj.tagName === 'BLOCKQUOTE') { + return 'HTMLQuoteElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltabledatacellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('td')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj instanceof HTMLElement && obj.tagName === 'TD') { + return 'HTMLTableDataCellElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltableheadercellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('th')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj instanceof HTMLElement && obj.tagName === 'TH') { + return 'HTMLTableHeaderCellElement'; + } + } + + /* ! Speed optimisation + * Pre: + * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) + * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) + * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) + * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) + * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) + * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) + * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) + * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) + * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) + * Post: + * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) + * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) + * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) + * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) + * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) + * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) + * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) + * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) + * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) + */ + var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); + if (typeof stringTag === 'string') { + return stringTag; + } + + var objPrototype = Object.getPrototypeOf(obj); + /* ! Speed optimisation + * Pre: + * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) + * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) + * Post: + * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) + * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) + */ + if (objPrototype === RegExp.prototype) { + return 'RegExp'; + } + + /* ! Speed optimisation + * Pre: + * date x 2,130,074 ops/sec ±4.42% (68 runs sampled) + * Post: + * date x 3,953,779 ops/sec ±1.35% (77 runs sampled) + */ + if (objPrototype === Date.prototype) { + return 'Date'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) + * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": + * Test: `Object.prototype.toString.call(Promise.resolve())`` + * - Chrome <=47 === "[object Object]" + * - Edge <=20 === "[object Object]" + * - Firefox 29-Latest === "[object Promise]" + * - Safari 7.1-Latest === "[object Promise]" + */ + if (promiseExists && objPrototype === Promise.prototype) { + return 'Promise'; + } + + /* ! Speed optimisation + * Pre: + * set x 2,222,186 ops/sec ±1.31% (82 runs sampled) + * Post: + * set x 4,545,879 ops/sec ±1.13% (83 runs sampled) + */ + if (setExists && objPrototype === Set.prototype) { + return 'Set'; + } + + /* ! Speed optimisation + * Pre: + * map x 2,396,842 ops/sec ±1.59% (81 runs sampled) + * Post: + * map x 4,183,945 ops/sec ±6.59% (82 runs sampled) + */ + if (mapExists && objPrototype === Map.prototype) { + return 'Map'; + } + + /* ! Speed optimisation + * Pre: + * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) + * Post: + * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) + */ + if (weakSetExists && objPrototype === WeakSet.prototype) { + return 'WeakSet'; + } + + /* ! Speed optimisation + * Pre: + * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) + * Post: + * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) + */ + if (weakMapExists && objPrototype === WeakMap.prototype) { + return 'WeakMap'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) + * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": + * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` + * - Edge <=13 === "[object Object]" + */ + if (dataViewExists && objPrototype === DataView.prototype) { + return 'DataView'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) + * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": + * Test: `Object.prototype.toString.call(new Map().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (mapExists && objPrototype === mapIteratorPrototype) { + return 'Map Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) + * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": + * Test: `Object.prototype.toString.call(new Set().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (setExists && objPrototype === setIteratorPrototype) { + return 'Set Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) + * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": + * Test: `Object.prototype.toString.call([][Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { + return 'Array Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) + * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": + * Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (stringIteratorExists && objPrototype === stringIteratorPrototype) { + return 'String Iterator'; + } + + /* ! Speed optimisation + * Pre: + * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) + * Post: + * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) + */ + if (objPrototype === null) { + return 'Object'; + } + + return Object + .prototype + .toString + .call(obj) + .slice(toStringLeftSliceLength, toStringRightSliceLength); +}; + +module.exports.typeDetect = module.exports; + +},{}]},{},[1])(1) +}); \ No newline at end of file diff --git a/node_modules/chai/index.js b/node_modules/chai/index.js new file mode 100644 index 000000000..634483b02 --- /dev/null +++ b/node_modules/chai/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/chai'); diff --git a/node_modules/chai/karma.conf.js b/node_modules/chai/karma.conf.js new file mode 100644 index 000000000..3dadb55c0 --- /dev/null +++ b/node_modules/chai/karma.conf.js @@ -0,0 +1,28 @@ +module.exports = function(config) { + config.set({ + frameworks: [ 'mocha' ] + , files: [ + 'chai.js' + , 'test/bootstrap/index.js' + , 'test/*.js' + ] + , reporters: [ 'progress' ] + , colors: true + , logLevel: config.LOG_INFO + , autoWatch: false + , browsers: [ 'PhantomJS' ] + , browserDisconnectTimeout: 10000 + , browserDisconnectTolerance: 2 + , browserNoActivityTimeout: 20000 + , singleRun: true + }); + + switch (process.env.CHAI_TEST_ENV) { + case 'sauce': + require('./karma.sauce')(config); + break; + default: + // ... + break; + }; +}; diff --git a/node_modules/chai/karma.sauce.js b/node_modules/chai/karma.sauce.js new file mode 100644 index 000000000..3d65b3e7d --- /dev/null +++ b/node_modules/chai/karma.sauce.js @@ -0,0 +1,41 @@ +var version = require('./package.json').version; +var ts = new Date().getTime(); + +module.exports = function(config) { + var auth; + + try { + auth = require('./test/auth/index'); + } catch(ex) { + auth = {}; + auth.SAUCE_USERNAME = process.env.SAUCE_USERNAME || null; + auth.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || null; + } + + if (!auth.SAUCE_USERNAME || !auth.SAUCE_ACCESS_KEY) return; + if (process.env.SKIP_SAUCE) return; + + var branch = process.env.TRAVIS_BRANCH || 'local' + var browserConfig = require('./sauce.browsers'); + var browsers = Object.keys(browserConfig); + var tags = [ 'chaijs_' + version, auth.SAUCE_USERNAME + '@' + branch ]; + var tunnel = process.env.TRAVIS_JOB_NUMBER || ts; + + if (process.env.TRAVIS_JOB_NUMBER) { + tags.push('travis@' + process.env.TRAVIS_JOB_NUMBER); + } + + config.browsers = config.browsers.concat(browsers); + config.customLaunchers = browserConfig; + config.reporters.push('saucelabs'); + config.captureTimeout = 300000; + + config.sauceLabs = { + username: auth.SAUCE_USERNAME + , accessKey: auth.SAUCE_ACCESS_KEY + , startConnect: ('TRAVIS' in process.env) === false + , tags: tags + , testName: 'ChaiJS' + , tunnelIdentifier: tunnel + }; +}; diff --git a/node_modules/chai/lib/chai.js b/node_modules/chai/lib/chai.js new file mode 100644 index 000000000..8c6363d3a --- /dev/null +++ b/node_modules/chai/lib/chai.js @@ -0,0 +1,92 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var used = []; + +/*! + * Chai version + */ + +exports.version = '4.1.2'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai. + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(exports, util); + used.push(fn); + } + + return exports; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); diff --git a/node_modules/chai/lib/chai/assertion.js b/node_modules/chai/lib/chai/assertion.js new file mode 100644 index 000000000..4d4217fb4 --- /dev/null +++ b/node_modules/chai/lib/chai/assertion.js @@ -0,0 +1,165 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * @param {Mixed} obj target of the assertion + * @param {String} msg (optional) custom error message + * @param {Function} ssfi (optional) starting point for removing stack frames + * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked + * @api private + */ + + function Assertion (obj, msg, ssfi, lockSsfi) { + flag(this, 'ssfi', ssfi || Assertion); + flag(this, 'lockSsfi', lockSsfi); + flag(this, 'object', obj); + flag(this, 'message', msg); + + return util.proxify(this); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (false !== showDiff) showDiff = true; + if (undefined === expected && undefined === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + msg = util.getMessage(this, arguments); + var actual = util.getActual(this, arguments); + throw new AssertionError(msg, { + actual: actual + , expected: expected + , showDiff: showDiff + }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; diff --git a/node_modules/chai/lib/chai/config.js b/node_modules/chai/lib/chai/config.js new file mode 100644 index 000000000..ca1e30a79 --- /dev/null +++ b/node_modules/chai/lib/chai/config.js @@ -0,0 +1,94 @@ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40, + + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {Boolean} + * @api public + */ + + useProxy: true, + + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @api public + */ + + proxyExcludedKeys: ['then', 'inspect', 'toJSON'] +}; diff --git a/node_modules/chai/lib/chai/core/assertions.js b/node_modules/chai/lib/chai/core/assertions.js new file mode 100644 index 000000000..1600b2c98 --- /dev/null +++ b/node_modules/chai/lib/chai/core/assertions.js @@ -0,0 +1,3729 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , AssertionError = chai.AssertionError + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to improve the readability + * of your assertions. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * - but + * - does + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been' + , 'is', 'and', 'has', 'have' + , 'with', 'that', 'which', 'at' + , 'of', 'same', 'but', 'does' ].forEach(function (chain) { + Assertion.addProperty(chain); + }); + + /** + * ### .not + * + * Negates all assertions that follow in the chain. + * + * expect(function () {}).to.not.throw(); + * expect({a: 1}).to.not.have.property('b'); + * expect([1, 2]).to.be.an('array').that.does.not.include(3); + * + * Just because you can negate any assertion with `.not` doesn't mean you + * should. With great power comes great responsibility. It's often best to + * assert that the one expected output was produced, rather than asserting + * that one of countless unexpected outputs wasn't produced. See individual + * assertions for specific guidance. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.equal(1); // Not recommended + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` + * assertions that follow in the chain to use deep equality instead of strict + * (`===`) equality. See the `deep-eql` project page for info on the deep + * equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .nested + * + * Enables dot- and bracket-notation in all `.property` and `.include` + * assertions that follow in the chain. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); + * + * `.nested` cannot be combined with `.own`. + * + * @name nested + * @namespace BDD + * @api public + */ + + Assertion.addProperty('nested', function () { + flag(this, 'nested', true); + }); + + /** + * ### .own + * + * Causes all `.property` and `.include` assertions that follow in the chain + * to ignore inherited properties. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.property('b').but.not.own.property('b'); + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * `.own` cannot be combined with `.nested`. + * + * @name own + * @namespace BDD + * @api public + */ + + Assertion.addProperty('own', function () { + flag(this, 'own', true); + }); + + /** + * ### .ordered + * + * Causes all `.members` assertions that follow in the chain to require that + * members be in the same order. + * + * expect([1, 2]).to.have.ordered.members([1, 2]) + * .but.not.have.ordered.members([2, 1]); + * + * When `.include` and `.ordered` are combined, the ordering begins at the + * start of both arrays. + * + * expect([1, 2, 3]).to.include.ordered.members([1, 2]) + * .but.not.include.ordered.members([2, 3]); + * + * @name ordered + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ordered', function () { + flag(this, 'ordered', true); + }); + + /** + * ### .any + * + * Causes all `.keys` assertions that follow in the chain to only require that + * the target have at least one of the given keys. This is the opposite of + * `.all`, which requires that the target have all of the given keys. + * + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false); + }); + + + /** + * ### .all + * + * Causes all `.keys` assertions that follow in the chain to require that the + * target have all of the given keys. This is the opposite of `.any`, which + * only requires that the target have at least one of the given keys. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` are + * added earlier in the chain. However, it's often best to add `.all` anyway + * because it improves readability. + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type[, msg]) + * + * Asserts that the target's type is equal to the given string `type`. Types + * are case insensitive. See the `type-detect` project page for info on the + * type detection algorithm: https://github.com/chaijs/type-detect. + * + * expect('foo').to.be.a('string'); + * expect({a: 1}).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(Promise.resolve()).to.be.a('promise'); + * expect(new Float32Array).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. + * + * var myObj = { + * [Symbol.toStringTag]: 'myCustomType' + * }; + * + * expect(myObj).to.be.a('myCustomType').but.not.an('object'); + * + * It's often best to use `.a` to check a target's type before making more + * assertions on the same target. That way, you avoid unexpected behavior from + * any assertion that does different things based on the target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.a`. However, it's often best to + * assert that the target is the expected type, rather than asserting that it + * isn't one of many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.an('array'); // Not recommended + * + * `.a` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * expect(1).to.be.a('string', 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.a('string'); + * + * `.a` can also be used as a language chain to improve the readability of + * your assertions. + * + * expect({b: 2}).to.have.a.property('b'); + * + * The alias `.an` can be used interchangeably with `.a`. + * + * @name a + * @alias an + * @param {String} type + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj).toLowerCase() + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(val[, msg]) + * + * When the target is a string, `.include` asserts that the given string `val` + * is a substring of the target. + * + * expect('foobar').to.include('foo'); + * + * When the target is an array, `.include` asserts that the given `val` is a + * member of the target. + * + * expect([1, 2, 3]).to.include(2); + * + * When the target is an object, `.include` asserts that the given object + * `val`'s properties are a subset of the target's properties. + * + * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); + * + * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a + * member of the target. SameValueZero equality algorithm is used. + * + * expect(new Set([1, 2])).to.include(2); + * + * When the target is a Map, `.include` asserts that the given `val` is one of + * the values of the target. SameValueZero equality algorithm is used. + * + * expect(new Map([['a', 1], ['b', 2]])).to.include(2); + * + * Because `.include` does different things based on the target's type, it's + * important to check the target's type before using `.include`. See the `.a` + * doc for info on testing a target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * + * By default, strict (`===`) equality is used to compare array members and + * object properties. Add `.deep` earlier in the chain to use deep equality + * instead (WeakSet targets are not supported). See the `deep-eql` project + * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * By default, all of the target's properties are searched when working with + * objects. This includes properties that are inherited and/or non-enumerable. + * Add `.own` earlier in the chain to exclude the target's inherited + * properties from the search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * Note that a target object is always only searched for `val`'s own + * enumerable properties. + * + * `.deep` and `.own` can be combined. + * + * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.include`. + * + * expect('foobar').to.not.include('taco'); + * expect([1, 2, 3]).to.not.include(4); + * + * However, it's dangerous to negate `.include` when the target is an object. + * The problem is that it creates uncertain expectations by asserting that the + * target object doesn't have all of `val`'s key/value pairs but may or may + * not have some of them. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target object isn't even expected to have `val`'s keys, it's + * often best to assert exactly that. + * + * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended + * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended + * + * When the target object is expected to have `val`'s keys, it's often best to + * assert that each of the properties has its expected value, rather than + * asserting that each property doesn't have one of many unexpected values. + * + * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended + * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended + * + * `.include` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.include(4); + * + * `.include` can also be used as a language chain, causing all `.members` and + * `.keys` assertions that follow in the chain to require the target to be a + * superset of the expected set, rather than an identical set. Note that + * `.members` ignores duplicates in the subset when `.include` is added. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * Note that adding `.any` earlier in the chain causes the `.keys` assertion + * to ignore `.include`. + * + * // Both assertions are identical + * expect({a: 1}).to.include.any.keys('a', 'b'); + * expect({a: 1}).to.have.any.keys('a', 'b'); + * + * The aliases `.includes`, `.contain`, and `.contains` can be used + * interchangeably with `.include`. + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function SameValueZero(a, b) { + return (_.isNaN(a) && _.isNaN(b)) || a === b; + } + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + if (msg) flag(this, 'message', msg); + + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , descriptor = isDeep ? 'deep ' : ''; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + var included = false; + + switch (objType) { + case 'string': + included = obj.indexOf(val) !== -1; + break; + + case 'weakset': + if (isDeep) { + throw new AssertionError( + flagMsg + 'unable to use .deep.include with WeakSet', + undefined, + ssfi + ); + } + + included = obj.has(val); + break; + + case 'map': + var isEql = isDeep ? _.eql : SameValueZero; + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + break; + + case 'set': + if (isDeep) { + obj.forEach(function (item) { + included = included || _.eql(item, val); + }); + } else { + included = obj.has(val); + } + break; + + case 'array': + if (isDeep) { + included = obj.some(function (item) { + return _.eql(item, val); + }) + } else { + included = obj.indexOf(val) !== -1; + } + break; + + default: + // This block is for asserting a subset of properties in an object. + // `_.expectTypes` isn't used here because `.include` should work with + // objects with a custom `@@toStringTag`. + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + 'object tested must be an array, a map, an object,' + + ' a set, a string, or a weakset, but ' + objType + ' given', + undefined, + ssfi + ); + } + + var props = Object.keys(val) + , firstErr = null + , numErrs = 0; + + props.forEach(function (prop) { + var propAssertion = new Assertion(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, 'lockSsfi', true); + + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + + // When validating .not.include with multiple properties, we only want + // to throw an assertion error if all of the properties are included, + // in which case we throw the first property assertion error that we + // encountered. + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + + // Assert inclusion in collection or substring in a string. + this.assert( + included + , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val) + , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is loosely (`==`) equal to `true`. However, it's + * often best to assert that the target is strictly (`===`) or deeply equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.ok; // Not recommended + * + * expect(true).to.be.true; // Recommended + * expect(true).to.be.ok; // Not recommended + * + * Add `.not` earlier in the chain to negate `.ok`. + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.not.be.ok; // Not recommended + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.ok; // Not recommended + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.be.ok; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.be.ok; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is strictly (`===`) equal to `true`. + * + * expect(true).to.be.true; + * + * Add `.not` earlier in the chain to negate `.true`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `true`. + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.true; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.true; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , flag(this, 'negate') ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is strictly (`===`) equal to `false`. + * + * expect(false).to.be.false; + * + * Add `.not` earlier in the chain to negate `.false`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `false`. + * + * expect(true).to.be.true; // Recommended + * expect(true).to.not.be.false; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.false; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(true, 'nooo why fail??').to.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , flag(this, 'negate') ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is strictly (`===`) equal to `null`. + * + * expect(null).to.be.null; + * + * Add `.not` earlier in the chain to negate `.null`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `null`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.null; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is strictly (`===`) equal to `undefined`. + * + * expect(undefined).to.be.undefined; + * + * Add `.not` earlier in the chain to negate `.undefined`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `undefined`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.undefined; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * + * Asserts that the target is exactly `NaN`. + * + * expect(NaN).to.be.NaN; + * + * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `NaN`. + * + * expect('foo').to.equal('foo'); // Recommended + * expect('foo').to.not.be.NaN; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + _.isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is not strictly (`===`) equal to either `null` or + * `undefined`. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.exist; // Not recommended + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.exist; // Not recommended + * + * Add `.not` earlier in the chain to negate `.exist`. + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.exist; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.exist; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(null, 'nooo why fail??').to.exist; + * + * @name exist + * @namespace BDD + * @api public + */ + + Assertion.addProperty('exist', function () { + var val = flag(this, 'object'); + this.assert( + val !== null && val !== undefined + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + }); + + /** + * ### .empty + * + * When the target is a string or array, `.empty` asserts that the target's + * `length` property is strictly (`===`) equal to `0`. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * + * When the target is a map or set, `.empty` asserts that the target's `size` + * property is strictly equal to `0`. + * + * expect(new Set()).to.be.empty; + * expect(new Map()).to.be.empty; + * + * When the target is a non-function object, `.empty` asserts that the target + * doesn't have any own enumerable properties. Properties with Symbol-based + * keys are excluded from the count. + * + * expect({}).to.be.empty; + * + * Because `.empty` does different things based on the target's type, it's + * important to check the target's type before using `.empty`. See the `.a` + * doc for info on testing a target's type. + * + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.empty`. However, it's often + * best to assert that the target contains its expected number of values, + * rather than asserting that it's not empty. + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.not.be.empty; // Not recommended + * + * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended + * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended + * + * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended + * expect({a: 1}).to.not.be.empty; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect([1, 2, 3], 'nooo why fail??').to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var val = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , itemsCount; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + switch (_.type(val).toLowerCase()) { + case 'array': + case 'string': + itemsCount = val.length; + break; + case 'map': + case 'set': + itemsCount = val.size; + break; + case 'weakmap': + case 'weakset': + throw new AssertionError( + flagMsg + '.empty was passed a weak collection', + undefined, + ssfi + ); + case 'function': + var msg = flagMsg + '.empty was passed a function ' + _.getName(val); + throw new AssertionError(msg.trim(), undefined, ssfi); + default: + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), + undefined, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + + this.assert( + 0 === itemsCount + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an `arguments` object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * test(); + * + * Add `.not` earlier in the chain to negate `.arguments`. However, it's often + * best to assert which type the target is expected to be, rather than + * asserting that its not an `arguments` object. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.arguments; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({}, 'nooo why fail??').to.be.arguments; + * + * The alias `.Arguments` can be used interchangeably with `.arguments`. + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = _.type(obj); + this.assert( + 'Arguments' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(val[, msg]) + * + * Asserts that the target is strictly (`===`) equal to the given `val`. + * + * expect(1).to.equal(1); + * expect('foo').to.equal('foo'); + * + * Add `.deep` earlier in the chain to use deep equality instead. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) equals `[1, 2]` + * expect([1, 2]).to.deep.equal([1, 2]); + * expect([1, 2]).to.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.equal`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to one of countless unexpected values. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.equal(2); // Not recommended + * + * `.equal` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.equal(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.equal(2); + * + * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. + * + * @name equal + * @alias equals + * @alias eq + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + return this.eql(val); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(obj[, msg]) + * + * Asserts that the target is deeply equal to the given `obj`. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object is deeply (but not strictly) equal to {a: 1} + * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); + * + * // Target array is deeply (but not strictly) equal to [1, 2] + * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.eql`. However, it's often best + * to assert that the target is deeply equal to its expected value, rather + * than not deeply equal to one of countless unexpected values. + * + * expect({a: 1}).to.eql({a: 1}); // Recommended + * expect({a: 1}).to.not.eql({b: 2}); // Not recommended + * + * `.eql` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); + * + * The alias `.eqls` can be used interchangeably with `.eql`. + * + * The `.deep.equal` assertion is almost identical to `.eql` but with one + * difference: `.deep.equal` causes deep equality comparisons to also be used + * for any other assertions that follow in the chain. + * + * @name eql + * @alias eqls + * @param {Mixed} obj + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + this.assert( + _.eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(n[, msg]) + * + * Asserts that the target is a number or a date greater than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.above(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is greater than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.above(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.above`. + * + * expect(2).to.equal(2); // Recommended + * expect(1).to.not.be.above(2); // Not recommended + * + * `.above` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.above(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.above(2); + * + * The aliases `.gt` and `.greaterThan` can be used interchangeably with + * `.above`. + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to above must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to above must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len > n + , 'expected #{this} to have a length above #{exp} but got #{act}' + , 'expected #{this} to not have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above #{exp}' + , 'expected #{this} to be at most #{exp}' + , n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(n[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `n` respectively. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.at.least(1); // Not recommended + * expect(2).to.be.at.least(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is greater than or equal to the given number + * `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.least(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.least`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.at.least(2); // Not recommended + * + * `.least` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.at.least(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.at.least(2); + * + * The alias `.gte` can be used interchangeably with `.least`. + * + * @name least + * @alias gte + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to least must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to least must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len >= n + , 'expected #{this} to have a length at least #{exp} but got #{act}' + , 'expected #{this} to have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least #{exp}' + , 'expected #{this} to be below #{exp}' + , n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + + /** + * ### .below(n[, msg]) + * + * Asserts that the target is a number or a date less than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.below(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is less than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.below(4); // Not recommended + * + * expect([1, 2, 3]).to.have.length(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.below`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.below(1); // Not recommended + * + * `.below` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.below(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.below(1); + * + * The aliases `.lt` and `.lessThan` can be used interchangeably with + * `.below`. + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to below must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to below must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len < n + , 'expected #{this} to have a length below #{exp} but got #{act}' + , 'expected #{this} to not have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below #{exp}' + , 'expected #{this} to be at least #{exp}' + , n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(n[, msg]) + * + * Asserts that the target is a number or a date less than or equal to the given number + * or date `n` respectively. However, it's often best to assert that the target is equal to its + * expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.at.most(2); // Not recommended + * expect(1).to.be.at.most(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is less than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.most(4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.most`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.at.most(1); // Not recommended + * + * `.most` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.at.most(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.at.most(1); + * + * The alias `.lte` can be used interchangeably with `.most`. + * + * @name most + * @alias lte + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , shouldThrow = true; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to most must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to most must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len <= n + , 'expected #{this} to have a length at most #{exp} but got #{act}' + , 'expected #{this} to have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most #{exp}' + , 'expected #{this} to be above #{exp}' + , n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + + /** + * ### .within(start, finish[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `start`, and less than or equal to the given number or date `finish` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.within(1, 3); // Not recommended + * expect(2).to.be.within(2, 3); // Not recommended + * expect(2).to.be.within(1, 2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the value of the + * target's `length` property is greater than or equal to the given number + * `start`, and less than or equal to the given number `finish`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.within`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.within(2, 4); // Not recommended + * + * `.within` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(4).to.be.within(1, 3, 'nooo why fail??'); + * expect(4, 'nooo why fail??').to.be.within(1, 3); + * + * @name within + * @param {Number} start lower bound inclusive + * @param {Number} finish upper bound inclusive + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , startType = _.type(start).toLowerCase() + , finishType = _.type(finish).toLowerCase() + , shouldThrow = true + , range = (startType === 'date' && finishType === 'date') + ? start.toUTCString() + '..' + finish.toUTCString() + : start + '..' + finish; + + if (doLength) { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) { + errorMessage = msgPrefix + 'the arguments to within must be dates'; + } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the arguments to within must be numbers'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var len = obj.length; + this.assert( + len >= start && len <= finish + , 'expected #{this} to have a length within ' + range + , 'expected #{this} to not have a length within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor[, msg]) + * + * Asserts that the target is an instance of the given `constructor`. + * + * function Cat () { } + * + * expect(new Cat()).to.be.an.instanceof(Cat); + * expect([1, 2]).to.be.an.instanceof(Array); + * + * Add `.not` earlier in the chain to negate `.instanceof`. + * + * expect({a: 1}).to.not.be.an.instanceof(Array); + * + * `.instanceof` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); + * + * Due to limitations in ES5, `.instanceof` may not always work as expected + * when using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing built-in object such as + * `Array`, `Error`, and `Map`. See your transpiler's docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * The alias `.instanceOf` can be used interchangeably with `.instanceof`. + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} msg _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + + var target = flag(this, 'object') + var ssfi = flag(this, 'ssfi'); + var flagMsg = flag(this, 'message'); + + try { + var isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The instanceof assertion needs a constructor but ' + + _.type(constructor) + ' was given.', + undefined, + ssfi + ); + } + throw err; + } + + var name = _.getName(constructor); + if (name === null) { + name = 'an unnamed constructor'; + } + + this.assert( + isInstanceOf + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name[, val[, msg]]) + * + * Asserts that the target has a property with the given key `name`. + * + * expect({a: 1}).to.have.property('a'); + * + * When `val` is provided, `.property` also asserts that the property's value + * is equal to the given `val`. + * + * expect({a: 1}).to.have.property('a', 1); + * + * By default, strict (`===`) equality is used. Add `.deep` earlier in the + * chain to use deep equality instead. See the `deep-eql` project page for + * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * The target's enumerable and non-enumerable properties are always included + * in the search. By default, both own and inherited properties are included. + * Add `.own` earlier in the chain to exclude inherited properties from the + * search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.own.property('a', 1); + * expect({a: 1}).to.have.property('b').but.not.own.property('b'); + * + * `.deep` and `.own` can be combined. + * + * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}) + * .to.have.deep.nested.property('a.b[0]', {c: 3}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.property`. + * + * expect({a: 1}).to.not.have.property('b'); + * + * However, it's dangerous to negate `.property` when providing `val`. The + * problem is that it creates uncertain expectations by asserting that the + * target either doesn't have a property with the given key `name`, or that it + * does have a property with the given key `name` but its value isn't equal to + * the given `val`. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target isn't expected to have a property with the given key + * `name`, it's often best to assert exactly that. + * + * expect({b: 2}).to.not.have.property('a'); // Recommended + * expect({b: 2}).to.not.have.property('a', 1); // Not recommended + * + * When the target is expected to have a property with the given key `name`, + * it's often best to assert that the property has its expected value, rather + * than asserting that it doesn't have one of many unexpected values. + * + * expect({a: 3}).to.have.property('a', 3); // Recommended + * expect({a: 3}).to.not.have.property('a', 1); // Not recommended + * + * `.property` changes the target of any assertions that follow in the chain + * to be the value of the property from the original target object. + * + * expect({a: 1}).to.have.property('a').that.is.a('number'); + * + * `.property` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing `val`, only use the + * second form. + * + * // Recommended + * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); + * expect({a: 1}, 'nooo why fail??').to.have.property('b'); + * + * // Not recommended + * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `val`. Instead, + * it's asserting that the target object has a `b` property that's equal to + * `undefined`. + * + * The assertions `.ownProperty` and `.haveOwnProperty` can be used + * interchangeably with `.own.property`. + * + * @name property + * @param {String} name + * @param {Mixed} val (optional) + * @param {String} msg _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + function assertProperty (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isNested = flag(this, 'nested') + , isOwn = flag(this, 'own') + , flagMsg = flag(this, 'message') + , obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi'); + + if (isNested && isOwn) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + undefined, + ssfi + ); + } + + if (obj === null || obj === undefined) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'Target cannot be null or undefined.', + undefined, + ssfi + ); + } + + var isDeep = flag(this, 'deep') + , negate = flag(this, 'negate') + , pathInfo = isNested ? _.getPathInfo(obj, name) : null + , value = isNested ? pathInfo.value : obj[name]; + + var descriptor = ''; + if (isDeep) descriptor += 'deep '; + if (isOwn) descriptor += 'own '; + if (isNested) descriptor += 'nested '; + descriptor += 'property '; + + var hasProperty; + if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) hasProperty = pathInfo.exists; + else hasProperty = _.hasProperty(obj, name); + + // When performing a negated assertion for both name and val, merely having + // a property with the given name isn't enough to cause the assertion to + // fail. It must both have a property with the given name, and the value of + // that property must equal the given val. Therefore, skip this assertion in + // favor of the next. + if (!negate || arguments.length === 1) { + this.assert( + hasProperty + , 'expected #{this} to have ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + hasProperty && (isDeep ? _.eql(val, value) : val === value) + , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + } + + Assertion.addMethod('property', assertProperty); + + function assertOwnProperty (name, value, msg) { + flag(this, 'own', true); + assertProperty.apply(this, arguments); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) + * + * Asserts that the target has its own property descriptor with the given key + * `name`. Enumerable and non-enumerable properties are included in the + * search. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a'); + * + * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that + * the property's descriptor is deeply equal to the given `descriptor`. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. + * + * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); + * + * However, it's dangerous to negate `.ownPropertyDescriptor` when providing + * a `descriptor`. The problem is that it creates uncertain expectations by + * asserting that the target either doesn't have a property descriptor with + * the given key `name`, or that it does have a property descriptor with the + * given key `name` but its not deeply equal to the given `descriptor`. It's + * often best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to have a property descriptor with the given + * key `name`, it's often best to assert exactly that. + * + * // Recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); + * + * // Not recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * When the target is expected to have a property descriptor with the given + * key `name`, it's often best to assert that the property has its expected + * descriptor, rather than asserting that it doesn't have one of many + * unexpected descriptors. + * + * // Recommended + * expect({a: 3}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 3, + * }); + * + * // Not recommended + * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * `.ownPropertyDescriptor` changes the target of any assertions that follow + * in the chain to be the value of the property descriptor from the original + * target object. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a') + * .that.has.property('enumerable', true); + * + * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a + * custom error message to show when the assertion fails. The message can also + * be given as the second argument to `expect`. When not providing + * `descriptor`, only use the second form. + * + * // Recommended + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }, 'nooo why fail??'); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); + * + * // Not recommended + * expect({a: 1}) + * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `descriptor`. + * Instead, it's asserting that the target object has a `b` property + * descriptor that's deeply equal to `undefined`. + * + * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with + * `.ownPropertyDescriptor`. + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + if (actualDescriptor && descriptor) { + this.assert( + _.eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .lengthOf(n[, msg]) + * + * Asserts that the target's `length` property is equal to the given number + * `n`. + * + * expect([1, 2, 3]).to.have.lengthOf(3); + * expect('foo').to.have.lengthOf(3); + * + * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often + * best to assert that the target's `length` property is equal to its expected + * value, rather than not equal to one of many unexpected values. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.not.have.lengthOf(4); // Not recommended + * + * `.lengthOf` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); + * + * `.lengthOf` can also be used as a language chain, causing all `.above`, + * `.below`, `.least`, `.most`, and `.within` assertions that follow in the + * chain to use the target's `length` property as the target. However, it's + * often best to assert that the target's `length` property is equal to its + * expected length, rather than asserting that its `length` property falls + * within some range of values. + * + * // Recommended + * expect([1, 2, 3]).to.have.lengthOf(3); + * + * // Not recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); + * expect([1, 2, 3]).to.have.lengthOf.below(4); + * expect([1, 2, 3]).to.have.lengthOf.at.least(3); + * expect([1, 2, 3]).to.have.lengthOf.at.most(3); + * expect([1, 2, 3]).to.have.lengthOf.within(2,4); + * + * Due to a compatibility issue, the alias `.length` can't be chained directly + * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used + * interchangeably with `.lengthOf` in every situation. It's recommended to + * always use `.lengthOf` instead of `.length`. + * + * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error + * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected + * + * @name lengthOf + * @alias length + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + var len = obj.length; + + this.assert( + len == n + , 'expected #{this} to have a length of #{exp} but got #{act}' + , 'expected #{this} to not have a length of #{act}' + , n + , len + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); + + /** + * ### .match(re[, msg]) + * + * Asserts that the target matches the given regular expression `re`. + * + * expect('foobar').to.match(/^foo/); + * + * Add `.not` earlier in the chain to negate `.match`. + * + * expect('foobar').to.not.match(/taco/); + * + * `.match` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect('foobar').to.match(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.match(/taco/); + * + * The alias `.matches` can be used interchangeably with `.match`. + * + * @name match + * @alias matches + * @param {RegExp} re + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(str[, msg]) + * + * Asserts that the target string contains the given substring `str`. + * + * expect('foobar').to.have.string('bar'); + * + * Add `.not` earlier in the chain to negate `.string`. + * + * expect('foobar').to.not.have.string('taco'); + * + * `.string` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect('foobar').to.have.string(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.have.string(/taco/); + * + * @name string + * @param {String} str + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + /** + * ### .keys(key1[, key2[, ...]]) + * + * Asserts that the target object, array, map, or set has the given keys. Only + * the target's own inherited properties are included in the search. + * + * When the target is an object or array, keys can be provided as one or more + * string arguments, a single array argument, or a single object argument. In + * the latter case, only the keys in the given object matter; the values are + * ignored. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * expect(['x', 'y']).to.have.all.keys(0, 1); + * + * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); + * expect(['x', 'y']).to.have.all.keys([0, 1]); + * + * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 + * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 + * + * When the target is a map or set, each key must be provided as a separate + * argument. + * + * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); + * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); + * + * Because `.keys` does different things based on the target's type, it's + * important to check the target's type before using `.keys`. See the `.a` doc + * for info on testing a target's type. + * + * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); + * + * By default, strict (`===`) equality is used to compare keys of maps and + * sets. Add `.deep` earlier in the chain to use deep equality instead. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); + * + * By default, the target must have all of the given keys and no more. Add + * `.any` earlier in the chain to only require that the target have at least + * one of the given keys. Also, add `.not` earlier in the chain to negate + * `.keys`. It's often best to add `.any` when negating `.keys`, and to use + * `.all` when asserting `.keys` without negation. + * + * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts + * exactly what's expected of the output, whereas `.not.all.keys` creates + * uncertain expectations. + * + * // Recommended; asserts that target doesn't have any of the given keys + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * // Not recommended; asserts that target doesn't have all of the given + * // keys but may or may not have some of them + * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); + * + * When asserting `.keys` without negation, `.all` is preferred because + * `.all.keys` asserts exactly what's expected of the output, whereas + * `.any.keys` creates uncertain expectations. + * + * // Recommended; asserts that target has all the given keys + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * // Not recommended; asserts that target has at least one of the given + * // keys but may or may not have more of them + * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` appear + * earlier in the chain. However, it's often best to add `.all` anyway because + * it improves readability. + * + * // Both assertions are identical + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended + * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended + * + * Add `.include` earlier in the chain to require that the target's keys be a + * superset of the expected keys, rather than identical sets. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * However, if `.any` and `.include` are combined, only the `.any` takes + * effect. The `.include` is ignored in this case. + * + * // Both assertions are identical + * expect({a: 1}).to.have.any.keys('a', 'b'); + * expect({a: 1}).to.include.any.keys('a', 'b'); + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.have.key('b'); + * + * The alias `.key` can be used interchangeably with `.keys`. + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , objType = _.type(obj) + , keysType = _.type(keys) + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , str + , deepStr = '' + , ok = true + , flagMsg = flag(this, 'message'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; + + if (objType === 'Map' || objType === 'Set') { + deepStr = isDeep ? 'deeply ' : ''; + actual = []; + + // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. + obj.forEach(function (val, key) { actual.push(key) }); + + if (keysType !== 'Array') { + keys = Array.prototype.slice.call(arguments); + } + + } else { + actual = _.getOwnEnumerableProperties(obj); + + switch (keysType) { + case 'Array': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + break; + case 'Object': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + // Only stringify non-Symbols because Symbols would become "Symbol()" + keys = keys.map(function (val) { + return typeof val === 'symbol' ? val : String(val); + }); + } + + if (!keys.length) { + throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); + } + + var len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all') + , expected = keys + , actual; + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + ok = expected.some(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + } + + // Has all + if (all) { + ok = expected.every(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + + if (!flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key) { + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + deepStr + str + , 'expected #{this} to not ' + deepStr + str + , expected.slice(0).sort(_.compareByInspect) + , actual.sort(_.compareByInspect) + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw([errorLike], [errMsgMatcher], [msg]) + * + * When no arguments are provided, `.throw` invokes the target function and + * asserts that an error is thrown. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(); + * + * When one argument is provided, and it's an error constructor, `.throw` + * invokes the target function and asserts that an error is thrown that's an + * instance of that error constructor. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError); + * + * When one argument is provided, and it's an error instance, `.throw` invokes + * the target function and asserts that an error is thrown that's strictly + * (`===`) equal to that error instance. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(err); + * + * When one argument is provided, and it's a string, `.throw` invokes the + * target function and asserts that an error is thrown with a message that + * contains that string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw('salmon'); + * + * When one argument is provided, and it's a regular expression, `.throw` + * invokes the target function and asserts that an error is thrown with a + * message that matches that regular expression. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(/salmon/); + * + * When two arguments are provided, and the first is an error instance or + * constructor, and the second is a string or regular expression, `.throw` + * invokes the function and asserts that an error is thrown that fulfills both + * conditions as described above. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); + * expect(badFn).to.throw(TypeError, /salmon/); + * expect(badFn).to.throw(err, 'salmon'); + * expect(badFn).to.throw(err, /salmon/); + * + * Add `.not` earlier in the chain to negate `.throw`. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); + * + * However, it's dangerous to negate `.throw` when providing any arguments. + * The problem is that it creates uncertain expectations by asserting that the + * target either doesn't throw an error, or that it throws an error but of a + * different type than the given type, or that it throws an error of the given + * type but with a message that doesn't include the given string. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to throw an error, it's often best to assert + * exactly that. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); // Recommended + * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * When the target is expected to throw an error, it's often best to assert + * that the error is of its expected type, and has a message that includes an + * expected string, rather than asserting that it doesn't have one of many + * unexpected types, and doesn't have a message that includes some string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended + * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * `.throw` changes the target of any assertions that follow in the chain to + * be the error object that's thrown. + * + * var err = new TypeError('Illegal salmon!'); + * err.code = 42; + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError).with.property('code', 42); + * + * `.throw` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. When not providing two arguments, always use + * the second form. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); + * expect(goodFn, 'nooo why fail??').to.throw(); + * + * Due to limitations in ES5, `.throw` may not always work as expected when + * using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing the built-in `Error` object and + * then passing the subclassed constructor to `.throw`. See your transpiler's + * docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * Beware of some common mistakes when using the `throw` assertion. One common + * mistake is to accidentally invoke the function yourself instead of letting + * the `throw` assertion invoke the function for you. For example, when + * testing if a function named `fn` throws, provide `fn` instead of `fn()` as + * the target for the assertion. + * + * expect(fn).to.throw(); // Good! Tests `fn` as desired + * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` + * + * If you need to assert that your function `fn` throws when passed certain + * arguments, then wrap a call to `fn` inside of another function. + * + * expect(function () { fn(42); }).to.throw(); // Function expression + * expect(() => fn(42)).to.throw(); // ES6 arrow function + * + * Another common mistake is to provide an object method (or any stand-alone + * function that relies on `this`) as the target of the assertion. Doing so is + * problematic because the `this` context will be lost when the function is + * invoked by `.throw`; there's no way for it to know what `this` is supposed + * to be. There are two ways around this problem. One solution is to wrap the + * method or function call inside of another function. Another solution is to + * use `bind`. + * + * expect(function () { cat.meow(); }).to.throw(); // Function expression + * expect(() => cat.meow()).to.throw(); // ES6 arrow function + * expect(cat.meow.bind(cat)).to.throw(); // Bind + * + * Finally, it's worth mentioning that it's a best practice in JavaScript to + * only throw `Error` and derivatives of `Error` such as `ReferenceError`, + * `TypeError`, and user-defined objects that extend `Error`. No other type of + * value will generate a stack trace when initialized. With that said, the + * `throw` assertion does technically support any type of value being thrown, + * not just `Error` and its derivatives. + * + * The aliases `.throws` and `.Throw` can be used interchangeably with + * `.throw`. + * + * @name throw + * @alias throws + * @alias Throw + * @param {Error|ErrorConstructor} errorLike + * @param {String|RegExp} errMsgMatcher error message + * @param {String} msg _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (errorLike, errMsgMatcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') || false; + new Assertion(obj, flagMsg, ssfi, true).is.a('function'); + + if (errorLike instanceof RegExp || typeof errorLike === 'string') { + errMsgMatcher = errorLike; + errorLike = null; + } + + var caughtErr; + try { + obj(); + } catch (err) { + caughtErr = err; + } + + // If we have the negate flag enabled and at least one valid argument it means we do expect an error + // but we want it to match a given set of criteria + var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; + + // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible + // See Issue #551 and PR #683@GitHub + var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + var errorLikeFail = false; + var errMsgMatcherFail = false; + + // Checking if error was thrown + if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { + // We need this to display results correctly according to their types + var errorLikeString = 'an error'; + if (errorLike instanceof Error) { + errorLikeString = '#{exp}'; + } else if (errorLike) { + errorLikeString = _.checkError.getConstructorName(errorLike); + } + + this.assert( + caughtErr + , 'expected #{this} to throw ' + errorLikeString + , 'expected #{this} to not throw an error but #{act} was thrown' + , errorLike && errorLike.toString() + , (caughtErr instanceof Error ? + caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr && + _.checkError.getConstructorName(caughtErr))) + ); + } + + if (errorLike && caughtErr) { + // We should compare instances only if `errorLike` is an instance of `Error` + if (errorLike instanceof Error) { + var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); + + if (isCompatibleInstance === negate) { + // These checks were created to ensure we won't fail too soon when we've got both args and a negate + // See Issue #551 and PR #683@GitHub + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '') + , errorLike.toString() + , caughtErr.toString() + ); + } + } + } + + var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + } + } + + if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { + // Here we check compatible messages + var placeholder = 'including'; + if (errMsgMatcher instanceof RegExp) { + placeholder = 'matching' + } + + var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}' + , 'expected #{this} to throw error not ' + placeholder + ' #{exp}' + , errMsgMatcher + , _.checkError.getMessage(caughtErr) + ); + } + } + } + + // If both assertions failed and both should've matched we throw an error + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + + flag(this, 'object', caughtErr); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method[, msg]) + * + * When the target is a non-function object, `.respondTo` asserts that the + * target has a method with the given name `method`. The method can be own or + * inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.respondTo('meow'); + * + * When the target is a function, `.respondTo` asserts that the target's + * `prototype` property has a method with the given name `method`. Again, the + * method can be own or inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(Cat).to.respondTo('meow'); + * + * Add `.itself` earlier in the chain to force `.respondTo` to treat the + * target as a non-function object, even if it's a function. Thus, it asserts + * that the target has a method with the given name `method`, rather than + * asserting that the target's `prototype` property has a method with the + * given name `method`. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * When not adding `.itself`, it's important to check the target's type before + * using `.respondTo`. See the `.a` doc for info on checking a target's type. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); + * + * Add `.not` earlier in the chain to negate `.respondTo`. + * + * function Dog () {} + * Dog.prototype.bark = function () {}; + * + * expect(new Dog()).to.not.respondTo('meow'); + * + * `.respondTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect({}).to.respondTo('meow', 'nooo why fail??'); + * expect({}, 'nooo why fail??').to.respondTo('meow'); + * + * The alias `.respondsTo` can be used interchangeably with `.respondTo`. + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === typeof obj && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Forces all `.respondTo` assertions that follow in the chain to behave as if + * the target is a non-function object, even if it's a function. Thus, it + * causes `.respondTo` to assert that the target has a method with the given + * name, rather than asserting that the target's `prototype` property has a + * method with the given name. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(matcher[, msg]) + * + * Invokes the given `matcher` function with the target being passed as the + * first argument, and asserts that the value returned is truthy. + * + * expect(1).to.satisfy(function(num) { + * return num > 0; + * }); + * + * Add `.not` earlier in the chain to negate `.satisfy`. + * + * expect(1).to.not.satisfy(function(num) { + * return num > 2; + * }); + * + * `.satisfy` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.satisfy(function(num) { + * return num > 2; + * }, 'nooo why fail??'); + * + * expect(1, 'nooo why fail??').to.satisfy(function(num) { + * return num > 2; + * }); + * + * The alias `.satisfies` can be used interchangeably with `.satisfy`. + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , flag(this, 'negate') ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta[, msg]) + * + * Asserts that the target is a number that's within a given +/- `delta` range + * of the given number `expected`. However, it's often best to assert that the + * target is equal to its expected value. + * + * // Recommended + * expect(1.5).to.equal(1.5); + * + * // Not recommended + * expect(1.5).to.be.closeTo(1, 0.5); + * expect(1.5).to.be.closeTo(2, 0.5); + * expect(1.5).to.be.closeTo(1, 1); + * + * Add `.not` earlier in the chain to negate `.closeTo`. + * + * expect(1.5).to.equal(1.5); // Recommended + * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended + * + * `.closeTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); + * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); + * + * The alias `.approximately` can be used interchangeably with `.closeTo`. + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).is.a('number'); + if (typeof expected !== 'number' || typeof delta !== 'number') { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'the arguments to closeTo or approximately must be numbers', + undefined, + ssfi + ); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + // Note: Duplicates are ignored if testing for inclusion instead of sameness. + function isSubsetOf(subset, superset, cmp, contains, ordered) { + if (!contains) { + if (subset.length !== superset.length) return false; + superset = superset.slice(); + } + + return subset.every(function(elem, idx) { + if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + + if (!cmp) { + var matchIdx = superset.indexOf(elem); + if (matchIdx === -1) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + } + + return superset.some(function(elem2, matchIdx) { + if (!cmp(elem, elem2)) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + }); + }); + } + + /** + * ### .members(set[, msg]) + * + * Asserts that the target array has the same members as the given array + * `set`. + * + * expect([1, 2, 3]).to.have.members([2, 1, 3]); + * expect([1, 2, 2]).to.have.members([2, 1, 2]); + * + * By default, members are compared using strict (`===`) equality. Add `.deep` + * earlier in the chain to use deep equality instead. See the `deep-eql` + * project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * By default, order doesn't matter. Add `.ordered` earlier in the chain to + * require that members appear in the same order. + * + * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); + * expect([1, 2, 3]).to.have.members([2, 1, 3]) + * .but.not.ordered.members([2, 1, 3]); + * + * By default, both arrays must be the same size. Add `.include` earlier in + * the chain to require that the target's members be a superset of the + * expected members. Note that duplicates are ignored in the subset when + * `.include` is added. + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * `.deep`, `.ordered`, and `.include` can all be combined. However, if + * `.include` and `.ordered` are combined, the ordering begins at the start of + * both arrays. + * + * expect([{a: 1}, {b: 2}, {c: 3}]) + * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) + * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); + * + * Add `.not` earlier in the chain to negate `.members`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the target array doesn't have all of the same members as + * the given array `set` but may or may not have some of them. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended + * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended + * + * `.members` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); + * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); + * + * @name members + * @param {Array} set + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).to.be.an('array'); + new Assertion(subset, flagMsg, ssfi, true).to.be.an('array'); + + var contains = flag(this, 'contains'); + var ordered = flag(this, 'ordered'); + + var subject, failMsg, failNegateMsg, lengthCheck; + + if (contains) { + subject = ordered ? 'an ordered superset' : 'a superset'; + failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; + failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; + } else { + subject = ordered ? 'ordered members' : 'members'; + failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; + failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; + } + + var cmp = flag(this, 'deep') ? _.eql : undefined; + + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered) + , failMsg + , failNegateMsg + , subset + , obj + , true + ); + }); + + /** + * ### .oneOf(list[, msg]) + * + * Asserts that the target is a member of the given array `list`. However, + * it's often best to assert that the target is equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended + * + * Comparisons are performed using strict (`===`) equality. + * + * Add `.not` earlier in the chain to negate `.oneOf`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended + * + * `.oneOf` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); + + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + + Assertion.addMethod('oneOf', oneOf); + + + /** + * ### .change(subject[, prop[, msg]]) + * + * When one argument is provided, `.change` asserts that the given function + * `subject` returns a different value when it's invoked before the target + * function compared to when it's invoked afterward. However, it's often best + * to assert that `subject` is equal to its expected value. + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * // Recommended + * expect(getDots()).to.equal(''); + * addDot(); + * expect(getDots()).to.equal('.'); + * + * // Not recommended + * expect(addDot).to.change(getDots); + * + * When two arguments are provided, `.change` asserts that the value of the + * given object `subject`'s `prop` property is different before invoking the + * target function compared to afterward. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * // Recommended + * expect(myObj).to.have.property('dots', ''); + * addDot(); + * expect(myObj).to.have.property('dots', '.'); + * + * // Not recommended + * expect(addDot).to.change(myObj, 'dots'); + * + * Strict (`===`) equality is used to compare before and after values. + * + * Add `.not` earlier in the chain to negate `.change`. + * + * var dots = '' + * , noop = function () {} + * , getDots = function () { return dots; }; + * + * expect(noop).to.not.change(getDots); + * + * var myObj = {dots: ''} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'dots'); + * + * `.change` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * expect(addDot, 'nooo why fail??').to.not.change(getDots); + * + * `.change` also causes all `.by` assertions that follow in the chain to + * assert how much a numeric subject was increased or decreased by. However, + * it's dangerous to use `.change.by`. The problem is that it creates + * uncertain expectations by asserting that the subject either increases by + * the given delta, or that it decreases by the given delta. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * The alias `.changes` can be used interchangeably with `.change`. + * + * @name change + * @alias changes + * @param {String} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + // This gets flagged because of the .by(delta) assertion + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'change'); + flag(this, 'realDelta', final !== initial); + + this.assert( + initial !== final + , 'expected ' + msgObj + ' to change' + , 'expected ' + msgObj + ' to not change' + ); + } + + Assertion.addMethod('change', assertChanges); + Assertion.addMethod('changes', assertChanges); + + /** + * ### .increase(subject[, prop[, msg]]) + * + * When one argument is provided, `.increase` asserts that the given function + * `subject` returns a greater number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.increase` also + * causes all `.by` assertions that follow in the chain to assert how much + * greater of a number is returned. It's often best to assert that the return + * value increased by the expected amount, rather than asserting it increased + * by any amount. + * + * var val = 1 + * , addTwo = function () { val += 2; } + * , getVal = function () { return val; }; + * + * expect(addTwo).to.increase(getVal).by(2); // Recommended + * expect(addTwo).to.increase(getVal); // Not recommended + * + * When two arguments are provided, `.increase` asserts that the value of the + * given object `subject`'s `prop` property is greater after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.increase(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.increase`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either decreases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to decrease, it's often best to assert that it + * decreased by the expected amount. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.increase(myObj, 'val'); // Not recommended + * + * `.increase` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.increase(getVal); + * + * The alias `.increases` can be used interchangeably with `.increase`. + * + * @name increase + * @alias increases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'increase'); + flag(this, 'realDelta', final - initial); + + this.assert( + final - initial > 0 + , 'expected ' + msgObj + ' to increase' + , 'expected ' + msgObj + ' to not increase' + ); + } + + Assertion.addMethod('increase', assertIncreases); + Assertion.addMethod('increases', assertIncreases); + + /** + * ### .decrease(subject[, prop[, msg]]) + * + * When one argument is provided, `.decrease` asserts that the given function + * `subject` returns a lesser number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.decrease` also + * causes all `.by` assertions that follow in the chain to assert how much + * lesser of a number is returned. It's often best to assert that the return + * value decreased by the expected amount, rather than asserting it decreased + * by any amount. + * + * var val = 1 + * , subtractTwo = function () { val -= 2; } + * , getVal = function () { return val; }; + * + * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended + * expect(subtractTwo).to.decrease(getVal); // Not recommended + * + * When two arguments are provided, `.decrease` asserts that the value of the + * given object `subject`'s `prop` property is lesser after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.decrease`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either increases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to increase, it's often best to assert that it + * increased by the expected amount. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended + * + * `.decrease` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.decrease(getVal); + * + * The alias `.decreases` can be used interchangeably with `.decrease`. + * + * @name decrease + * @alias decreases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'decrease'); + flag(this, 'realDelta', initial - final); + + this.assert( + final - initial < 0 + , 'expected ' + msgObj + ' to decrease' + , 'expected ' + msgObj + ' to not decrease' + ); + } + + Assertion.addMethod('decrease', assertDecreases); + Assertion.addMethod('decreases', assertDecreases); + + /** + * ### .by(delta[, msg]) + * + * When following an `.increase` assertion in the chain, `.by` asserts that + * the subject of the `.increase` assertion increased by the given `delta`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * When following a `.decrease` assertion in the chain, `.by` asserts that the + * subject of the `.decrease` assertion decreased by the given `delta`. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); + * + * When following a `.change` assertion in the chain, `.by` asserts that the + * subject of the `.change` assertion either increased or decreased by the + * given `delta`. However, it's dangerous to use `.change.by`. The problem is + * that it creates uncertain expectations. It's often best to identify the + * exact output that's expected, and then write an assertion that only accepts + * that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.by`. However, it's often best + * to assert that the subject changed by its expected delta, rather than + * asserting that it didn't change by one of countless unexpected deltas. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * // Recommended + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * // Not recommended + * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); + * + * `.by` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); + * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); + * + * @name by + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDelta(delta, msg) { + if (msg) flag(this, 'message', msg); + + var msgObj = flag(this, 'deltaMsgObj'); + var initial = flag(this, 'initialDeltaValue'); + var final = flag(this, 'finalDeltaValue'); + var behavior = flag(this, 'deltaBehavior'); + var realDelta = flag(this, 'realDelta'); + + var expression; + if (behavior === 'change') { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + + this.assert( + expression + , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta + , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta + ); + } + + Assertion.addMethod('by', assertDelta); + + /** + * ### .extensible + * + * Asserts that the target is extensible, which means that new properties can + * be added to it. Primitives are never extensible. + * + * expect({a: 1}).to.be.extensible; + * + * Add `.not` earlier in the chain to negate `.extensible`. + * + * var nonExtensibleObject = Object.preventExtensions({}) + * , sealedObject = Object.seal({}) + * , frozenObject = Object.freeze({}); + * + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * expect(1).to.not.be.extensible; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(1, 'nooo why fail??').to.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior for ES5 environments. + + var isExtensible = obj === Object(obj) && Object.isExtensible(obj); + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed, which means that new properties can't be + * added to it, and its existing properties can't be reconfigured or deleted. + * However, it's possible that its existing properties can still be reassigned + * to different values. Primitives are always sealed. + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect(1).to.be.sealed; + * + * Add `.not` earlier in the chain to negate `.sealed`. + * + * expect({a: 1}).to.not.be.sealed; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior for ES5 environments. + + var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen, which means that new properties can't be + * added to it, and its existing properties can't be reassigned to different + * values, reconfigured, or deleted. Primitives are always frozen. + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect(1).to.be.frozen; + * + * Add `.not` earlier in the chain to negate `.frozen`. + * + * expect({a: 1}).to.not.be.frozen; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior for ES5 environments. + + var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); + + /** + * ### .finite + * + * Asserts that the target is a number, and isn't `NaN` or positive/negative + * `Infinity`. + * + * expect(1).to.be.finite; + * + * Add `.not` earlier in the chain to negate `.finite`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either isn't a number, or that it's `NaN`, or + * that it's positive `Infinity`, or that it's negative `Infinity`. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to be a number, it's often best to assert + * that it's the expected type, rather than asserting that it isn't one of + * many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.finite; // Not recommended + * + * When the target is expected to be `NaN`, it's often best to assert exactly + * that. + * + * expect(NaN).to.be.NaN; // Recommended + * expect(NaN).to.not.be.finite; // Not recommended + * + * When the target is expected to be positive infinity, it's often best to + * assert exactly that. + * + * expect(Infinity).to.equal(Infinity); // Recommended + * expect(Infinity).to.not.be.finite; // Not recommended + * + * When the target is expected to be negative infinity, it's often best to + * assert exactly that. + * + * expect(-Infinity).to.equal(-Infinity); // Recommended + * expect(-Infinity).to.not.be.finite; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect('foo', 'nooo why fail??').to.be.finite; + * + * @name finite + * @namespace BDD + * @api public + */ + + Assertion.addProperty('finite', function(msg) { + var obj = flag(this, 'object'); + + this.assert( + typeof obj === "number" && isFinite(obj) + , 'expected #{this} to be a finite number' + , 'expected #{this} to not be a finite number' + ); + }); +}; diff --git a/node_modules/chai/lib/chai/interface/assert.js b/node_modules/chai/lib/chai/interface/assert.js new file mode 100644 index 000000000..fa7719157 --- /dev/null +++ b/node_modules/chai/lib/chai/interface/assert.js @@ -0,0 +1,3098 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + + +module.exports = function (chai, util) { + + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert, true); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg, assert.isOk, true).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg, assert.isNotOk, true).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal, true); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual, true); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @alias deepStrictEqual + * @namespace Assert + * @api public + */ + + assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg, assert.isTrue, true).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg, assert.isFalse, true).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg, assert.isNull, true).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); + }; + + /** + * ### .isNaN + * + * Asserts that value is NaN. + * + * assert.isNaN(NaN, 'NaN is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg, assert.isNaN, true).to.be.NaN; + }; + + /** + * ### .isNotNaN + * + * Asserts that value is not NaN. + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN; + }; + + /** + * ### .exists + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * assert.exists(foo, 'foo is neither `null` nor `undefined`'); + * + * @name exists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.exists = function (val, msg) { + new Assertion(val, msg, assert.exists, true).to.exist; + }; + + /** + * ### .notExists + * + * Asserts that the target is either `null` or `undefined`. + * + * var bar = null + * , baz; + * + * assert.notExists(bar); + * assert.notExists(baz, 'baz is either null or undefined'); + * + * @name notExists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notExists = function (val, msg) { + new Assertion(val, msg, assert.notExists, true).to.not.exist; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg, assert.isFunction, true).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg, assert.isObject, true).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg, assert.isArray, true).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg, assert.isString, true).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); + }; + + /** + * ### .isFinite(value, [message]) + * + * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * var cups = 2; + * assert.isFinite(cups, 'how many cups'); + * + * assert.isFinite(NaN); // throws + * + * @name isFinite + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFinite = function (val, msg) { + new Assertion(val, msg, assert.isFinite, true).to.be.finite; + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg, assert.typeOf, true).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.notInstanceOf, true) + .to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.include([1,2,3], 2, 'array contains value'); + * assert.include('foobar', 'foo', 'string contains substring'); + * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); + * + * Strict equality (===) is used. When asserting the inclusion of a value in + * an array, the array is searched for an element that's strictly equal to the + * given value. When asserting a subset of properties in an object, the object + * is searched for the given property keys, checking that each one is present + * and stricty equal to the given property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.include([obj1, obj2], obj1); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include, true).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.notInclude([1,2,3], 4, 'array doesn't contain value'); + * assert.notInclude('foobar', 'baz', 'string doesn't contain substring'); + * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); + * + * Strict equality (===) is used. When asserting the absence of a value in an + * array, the array is searched to confirm the absence of an element that's + * strictly equal to the given value. When asserting a subset of properties in + * an object, the object is searched to confirm that at least one of the given + * property keys is either not present or not strictly equal to the given + * property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notInclude([obj1, obj2], {a: 1}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude, true).not.include(inc); + }; + + /** + * ### .deepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.deepInclude([obj1, obj2], {a: 1}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); + * + * @name deepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); + }; + + /** + * ### .notDeepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notDeepInclude([obj1, obj2], {a: 9}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); + * + * @name notDeepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); + }; + + /** + * ### .nestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); + * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); + * + * @name nestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); + }; + + /** + * ### .notNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); + * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); + * + * @name notNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notNestedInclude, true) + .not.nested.include(inc); + }; + + /** + * ### .deepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); + * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); + * + * @name deepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepNestedInclude, true) + .deep.nested.include(inc); + }; + + /** + * ### .notDeepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) + * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); + * + * @name notDeepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepNestedInclude, true) + .not.deep.nested.include(inc); + }; + + /** + * ### .ownInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties. + * + * assert.ownInclude({ a: 1 }, { a: 1 }); + * + * @name ownInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.ownInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); + }; + + /** + * ### .notOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties. + * + * Object.prototype.b = 2; + * + * assert.notOwnInclude({ a: 1 }, { b: 2 }); + * + * @name notOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); + }; + + /** + * ### .deepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); + * + * @name deepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepOwnInclude, true) + .deep.own.include(inc); + }; + + /** + * ### .notDeepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); + * + * @name notDeepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepOwnInclude, true) + .not.deep.own.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg, assert.match, true).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * assert.property({ tea: { green: 'matcha' }}, 'toString'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg, assert.property, true).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notProperty, true) + .to.not.have.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a strict equality check + * (===). + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.propertyVal, true) + .to.have.property(prop, val); + }; + + /** + * ### .notPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a strict equality check + * (===). + * + * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); + * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); + * + * @name notPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notPropertyVal, true) + .to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a deep equality check. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepPropertyVal, true) + .to.have.deep.property(prop, val); + }; + + /** + * ### .notDeepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a deep equality check. + * + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * + * @name notDeepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepPropertyVal, true) + .to.not.have.deep.property(prop, val); + }; + + /** + * ### .ownProperty(object, property, [message]) + * + * Asserts that `object` has a direct property named by `property`. Inherited + * properties aren't checked. + * + * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); + * + * @name ownProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.ownProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.ownProperty, true) + .to.have.own.property(prop); + }; + + /** + * ### .notOwnProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct property named by + * `property`. Inherited properties aren't checked. + * + * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); + * assert.notOwnProperty({}, 'toString'); + * + * @name notOwnProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.notOwnProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notOwnProperty, true) + .to.not.have.own.property(prop); + }; + + /** + * ### .ownPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a strict equality check (===). + * Inherited properties aren't checked. + * + * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); + * + * @name ownPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.ownPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.ownPropertyVal, true) + .to.have.own.property(prop, value); + }; + + /** + * ### .notOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a strict equality check + * (===). Inherited properties aren't checked. + * + * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); + * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notOwnPropertyVal, true) + .to.not.have.own.property(prop, value); + }; + + /** + * ### .deepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a deep equality check. Inherited + * properties aren't checked. + * + * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.deepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.deepOwnPropertyVal, true) + .to.have.deep.own.property(prop, value); + }; + + /** + * ### .notDeepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a deep equality check. + * Inherited properties aren't checked. + * + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notDeepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true) + .to.not.have.deep.own.property(prop, value); + }; + + /** + * ### .nestedProperty(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`, which can be a string using dot- and bracket-notation for + * nested reference. + * + * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name nestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.nestedProperty, true) + .to.have.nested.property(prop); + }; + + /** + * ### .notNestedProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for nested reference. The + * property cannot exist on the object nor anywhere in its prototype chain. + * + * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notNestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notNestedProperty, true) + .to.not.have.nested.property(prop); + }; + + /** + * ### .nestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a strict equality check (===). + * + * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name nestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.nestedPropertyVal, true) + .to.have.nested.property(prop, val); + }; + + /** + * ### .notNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a strict equality check (===). + * + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); + * + * @name notNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notNestedPropertyVal, true) + .to.not.have.nested.property(prop, val); + }; + + /** + * ### .deepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with a value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a deep equality check. + * + * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); + * + * @name deepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepNestedPropertyVal, true) + .to.have.deep.nested.property(prop, val); + }; + + /** + * ### .notDeepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a deep equality check. + * + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); + * + * @name notDeepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true) + .to.not.have.deep.nested.property(prop, val); + } + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` property with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); + }; + + /** + * ### .hasAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); + * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAnyKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); + } + + /** + * ### .hasAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); + * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); + } + + /** + * ### .containsAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name containsAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllKeys, true) + .to.contain.all.keys(keys); + } + + /** + * ### .doesNotHaveAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAnyKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true) + .to.not.have.any.keys(keys); + } + + /** + * ### .doesNotHaveAllKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllKeys, true) + .to.not.have.all.keys(keys); + } + + /** + * ### .hasAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyDeepKeys, true) + .to.have.any.deep.keys(keys); + } + + /** + * ### .hasAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); + * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllDeepKeys, true) + .to.have.all.deep.keys(keys); + } + + /** + * ### .containsAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name containsAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllDeepKeys, true) + .to.contain.all.deep.keys(keys); + } + + /** + * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAnyDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true) + .to.not.have.any.deep.keys(keys); + } + + /** + * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true) + .to.not.have.all.deep.keys(keys); + } + + /** + * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a + * message matching `errMsgMatcher`. + * + * assert.throws(fn, 'function throws a reference error'); + * assert.throws(fn, /function throws a reference error/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, errorInstance); + * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); + * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); + * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); + * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} fn + * @param {ErrorConstructor|Error} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + var assertErr = new Assertion(fn, msg, assert.throws, true) + .to.throw(errorLike, errMsgMatcher); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a + * message matching `errMsgMatcher`. + * + * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); + * assert.doesNotThrow(fn, /Any Error thrown must not match this/); + * assert.doesNotThrow(fn, Error); + * assert.doesNotThrow(fn, errorInstance); + * assert.doesNotThrow(fn, Error, 'Error must not have this message'); + * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); + * assert.doesNotThrow(fn, Error, /Error must not match this/); + * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); + * + * @name doesNotThrow + * @param {Function} fn + * @param {ErrorConstructor} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + new Assertion(fn, msg, assert.doesNotThrow, true) + .to.not.throw(errorLike, errMsgMatcher); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + msg = msg ? msg + ': ' : msg; + throw new chai.AssertionError( + msg + 'Invalid operator "' + operator + '"', + undefined, + assert.operator + ); + } + var test = new Assertion(ok, msg, assert.operator, true); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.approximately, true) + .to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * strict equality check (===). + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameMembers, true) + .to.have.same.members(set2); + } + + /** + * ### .notSameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a strict equality check (===). + * + * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); + * + * @name notSameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameMembers, true) + .to.not.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * deep equality check. + * + * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepMembers, true) + .to.have.same.deep.members(set2); + } + + /** + * ### .notSameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a deep equality check. + * + * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); + * + * @name notSameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepMembers, true) + .to.not.have.same.deep.members(set2); + } + + /** + * ### .sameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a strict equality check (===). + * + * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); + * + * @name sameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameOrderedMembers, true) + .to.have.same.ordered.members(set2); + } + + /** + * ### .notSameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a strict equality check (===). + * + * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); + * + * @name notSameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameOrderedMembers, true) + .to.not.have.same.ordered.members(set2); + } + + /** + * ### .sameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a deep equality check. + * + * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); + * + * @name sameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepOrderedMembers, true) + .to.have.same.deep.ordered.members(set2); + } + + /** + * ### .notSameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a deep equality check. + * + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); + * + * @name notSameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true) + .to.not.have.same.deep.ordered.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeMembers, true) + .to.include.members(subset); + } + + /** + * ### .notIncludeMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); + * + * @name notIncludeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeMembers, true) + .to.not.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a deep + * equality check. Duplicates are ignored. + * + * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepMembers, true) + .to.include.deep.members(subset); + } + + /** + * ### .notIncludeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * deep equality check. Duplicates are ignored. + * + * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); + * + * @name notIncludeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepMembers, true) + .to.not.include.deep.members(subset); + } + + /** + * ### .includeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); + * + * @name includeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeOrderedMembers, true) + .to.include.ordered.members(subset); + } + + /** + * ### .notIncludeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); + * + * @name notIncludeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeOrderedMembers, true) + .to.not.include.ordered.members(subset); + } + + /** + * ### .includeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); + * + * @name includeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepOrderedMembers, true) + .to.include.deep.ordered.members(subset); + } + + /** + * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); + * + * @name notIncludeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true) + .to.not.include.deep.ordered.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property, [message]) + * + * Asserts that a function changes the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); + } + + /** + * ### .changesBy(function, object, property, delta, [message]) + * + * Asserts that a function changes the value of a property by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 2 }; + * assert.changesBy(fn, obj, 'val', 2); + * + * @name changesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesBy, true) + .to.change(obj, prop).by(delta); + } + + /** + * ### .doesNotChange(function, object, property, [message]) + * + * Asserts that a function does not change the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotChange, true) + .to.not.change(obj, prop); + } + + /** + * ### .changesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.changesButNotBy(fn, obj, 'val', 5); + * + * @name changesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesButNotBy, true) + .to.change(obj, prop).but.not.by(delta); + } + + /** + * ### .increases(function, object, property, [message]) + * + * Asserts that a function increases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.increases, true) + .to.increase(obj, prop); + } + + /** + * ### .increasesBy(function, object, property, delta, [message]) + * + * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.increasesBy(fn, obj, 'val', 10); + * + * @name increasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesBy, true) + .to.increase(obj, prop).by(delta); + } + + /** + * ### .doesNotIncrease(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotIncrease, true) + .to.not.increase(obj, prop); + } + + /** + * ### .increasesButNotBy(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.increasesButNotBy(fn, obj, 'val', 10); + * + * @name increasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesButNotBy, true) + .to.increase(obj, prop).but.not.by(delta); + } + + /** + * ### .decreases(function, object, property, [message]) + * + * Asserts that a function decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.decreases, true) + .to.decrease(obj, prop); + } + + /** + * ### .decreasesBy(function, object, property, delta, [message]) + * + * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val -= 5 }; + * assert.decreasesBy(fn, obj, 'val', 5); + * + * @name decreasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesBy, true) + .to.decrease(obj, prop).by(delta); + } + + /** + * ### .doesNotDecrease(function, object, property, [message]) + * + * Asserts that a function does not decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecrease, true) + .to.not.decrease(obj, prop); + } + + /** + * ### .doesNotDecreaseBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.doesNotDecreaseBy(fn, obj, 'val', 1); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecreaseBy, true) + .to.not.decrease(obj, prop).by(delta); + } + + /** + * ### .decreasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreasesButNotBy(fn, obj, 'val', 1); + * + * @name decreasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesButNotBy, true) + .to.decrease(obj, prop).but.not.by(delta); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; + }; + + /** + * ### .isEmpty(target) + * + * Asserts that the target does not contain any values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isEmpty([]); + * assert.isEmpty(''); + * assert.isEmpty(new Map); + * assert.isEmpty({}); + * + * @name isEmpty + * @alias empty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isEmpty = function(val, msg) { + new Assertion(val, msg, assert.isEmpty, true).to.be.empty; + }; + + /** + * ### .isNotEmpty(target) + * + * Asserts that the target contains values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isNotEmpty([1, 2]); + * assert.isNotEmpty('34'); + * assert.isNotEmpty(new Set([5, 6])); + * assert.isNotEmpty({ key: 7 }); + * + * @name isNotEmpty + * @alias notEmpty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotEmpty = function(val, msg) { + new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen') + ('isEmpty', 'empty') + ('isNotEmpty', 'notEmpty'); +}; diff --git a/node_modules/chai/lib/chai/interface/expect.js b/node_modules/chai/lib/chai/interface/expect.js new file mode 100644 index 000000000..8c34072fb --- /dev/null +++ b/node_modules/chai/lib/chai/interface/expect.js @@ -0,0 +1,34 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; diff --git a/node_modules/chai/lib/chai/interface/should.js b/node_modules/chai/lib/chai/interface/should.js new file mode 100644 index 000000000..d7525b955 --- /dev/null +++ b/node_modules/chai/lib/chai/interface/should.js @@ -0,0 +1,204 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String + || this instanceof Number + || this instanceof Boolean + || typeof Symbol === 'function' && this instanceof Symbol) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; diff --git a/node_modules/chai/lib/chai/utils/addChainableMethod.js b/node_modules/chai/lib/chai/utils/addChainableMethod.js new file mode 100644 index 000000000..a713f6ac8 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addChainableMethod.js @@ -0,0 +1,152 @@ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/*! + * Module variables + */ + +// Check whether `Object.setPrototypeOf` is supported +var canSetPrototype = typeof Object.setPrototypeOf === 'function'; + +// Without `Object.setPrototypeOf` support, this module will need to add properties to a function. +// However, some of functions' own props are not configurable and should be skipped. +var testFn = function() {}; +var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { + var propDesc = Object.getOwnPropertyDescriptor(testFn, name); + + // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, + // but then returns `undefined` as the property descriptor for `callee`. As a + // workaround, we perform an otherwise unnecessary type-check for `propDesc`, + // and then filter it out if it's not an object as it should be. + if (typeof propDesc !== 'object') + return true; + + return !propDesc.configurable; +}); + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### .addChainableMethod(ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + + var chainableMethodWrapper = function () { + // Setting the `ssfi` flag to `chainableMethodWrapper` causes this + // function to be the starting point for removing implementation + // frames from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then this assertion is being + // invoked from inside of another assertion. In this case, the `ssfi` + // flag has already been set by the outer assertion. + // + // Note that overwriting a chainable method merely replaces the saved + // methods in `ctx.__methods` instead of completely replacing the + // overwritten assertion. Therefore, an overwriting assertion won't + // set the `ssfi` or `lockSsfi` flags. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', chainableMethodWrapper); + } + + var result = chainableBehavior.method.apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(chainableMethodWrapper, name, true); + + // Use `Object.setPrototypeOf` if available + if (canSetPrototype) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + } + , configurable: true + }); +}; diff --git a/node_modules/chai/lib/chai/utils/addLengthGuard.js b/node_modules/chai/lib/chai/utils/addLengthGuard.js new file mode 100644 index 000000000..1f27e8b25 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addLengthGuard.js @@ -0,0 +1,62 @@ +var config = require('../config'); + +var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); + +/*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .addLengthGuard(fn, assertionName, isChainable) + * + * Define `length` as a getter on the given uninvoked method assertion. The + * getter acts as a guard against chaining `length` directly off of an uninvoked + * method assertion, which is a problem because it references `function`'s + * built-in `length` property instead of Chai's `length` assertion. When the + * getter catches the user making this mistake, it throws an error with a + * helpful message. + * + * There are two ways in which this mistake can be made. The first way is by + * chaining the `length` assertion directly off of an uninvoked chainable + * method. In this case, Chai suggests that the user use `lengthOf` instead. The + * second way is by chaining the `length` assertion directly off of an uninvoked + * non-chainable method. Non-chainable methods must be invoked prior to + * chaining. In this case, Chai suggests that the user consult the docs for the + * given assertion. + * + * If the `length` property of functions is unconfigurable, then return `fn` + * without modification. + * + * Note that in ES6, the function's `length` property is configurable, so once + * support for legacy environments is dropped, Chai's `length` property can + * replace the built-in function's `length` property, and this length guard will + * no longer be necessary. In the mean time, maintaining consistency across all + * environments is the priority. + * + * @param {Function} fn + * @param {String} assertionName + * @param {Boolean} isChainable + * @namespace Utils + * @name addLengthGuard + */ + +module.exports = function addLengthGuard (fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) return fn; + + Object.defineProperty(fn, 'length', { + get: function () { + if (isChainable) { + throw Error('Invalid Chai property: ' + assertionName + '.length. Due' + + ' to a compatibility issue, "length" cannot directly follow "' + + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); + } + + throw Error('Invalid Chai property: ' + assertionName + '.length. See' + + ' docs for proper usage of "' + assertionName + '".'); + } + }); + + return fn; +}; diff --git a/node_modules/chai/lib/chai/utils/addMethod.js b/node_modules/chai/lib/chai/utils/addMethod.js new file mode 100644 index 000000000..021f08042 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addMethod.js @@ -0,0 +1,68 @@ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addMethod(ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ + +module.exports = function addMethod(ctx, name, method) { + var methodWrapper = function () { + // Setting the `ssfi` flag to `methodWrapper` causes this function to be the + // starting point for removing implementation frames from the stack trace of + // a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', methodWrapper); + } + + var result = method.apply(this, arguments); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); +}; diff --git a/node_modules/chai/lib/chai/utils/addProperty.js b/node_modules/chai/lib/chai/utils/addProperty.js new file mode 100644 index 000000000..872a8cd7e --- /dev/null +++ b/node_modules/chai/lib/chai/utils/addProperty.js @@ -0,0 +1,72 @@ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addProperty(ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function addProperty(ctx, name, getter) { + getter = getter === undefined ? function () {} : getter; + + Object.defineProperty(ctx, name, + { get: function propertyGetter() { + // Setting the `ssfi` flag to `propertyGetter` causes this function to + // be the starting point for removing implementation frames from the + // stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', propertyGetter); + } + + var result = getter.call(this); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; diff --git a/node_modules/chai/lib/chai/utils/compareByInspect.js b/node_modules/chai/lib/chai/utils/compareByInspect.js new file mode 100644 index 000000000..fde48d46c --- /dev/null +++ b/node_modules/chai/lib/chai/utils/compareByInspect.js @@ -0,0 +1,31 @@ +/*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var inspect = require('./inspect'); + +/** + * ### .compareByInspect(mixed, mixed) + * + * To be used as a compareFunction with Array.prototype.sort. Compares elements + * using inspect instead of default behavior of using toString so that Symbols + * and objects with irregular/missing toString can still be sorted without a + * TypeError. + * + * @param {Mixed} first element to compare + * @param {Mixed} second element to compare + * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1 + * @name compareByInspect + * @namespace Utils + * @api public + */ + +module.exports = function compareByInspect(a, b) { + return inspect(a) < inspect(b) ? -1 : 1; +}; diff --git a/node_modules/chai/lib/chai/utils/expectTypes.js b/node_modules/chai/lib/chai/utils/expectTypes.js new file mode 100644 index 000000000..6293db748 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/expectTypes.js @@ -0,0 +1,51 @@ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function expectTypes(obj, types) { + var flagMsg = flag(obj, 'message'); + var ssfi = flag(obj, 'ssfi'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + var objType = type(obj).toLowerCase(); + + if (!types.some(function (expected) { return objType === expected; })) { + throw new AssertionError( + flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', + undefined, + ssfi + ); + } +}; diff --git a/node_modules/chai/lib/chai/utils/flag.js b/node_modules/chai/lib/chai/utils/flag.js new file mode 100644 index 000000000..dd53bfbf8 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/flag.js @@ -0,0 +1,33 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function flag(obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; diff --git a/node_modules/chai/lib/chai/utils/getActual.js b/node_modules/chai/lib/chai/utils/getActual.js new file mode 100644 index 000000000..976e11259 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getActual.js @@ -0,0 +1,20 @@ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; diff --git a/node_modules/chai/lib/chai/utils/getEnumerableProperties.js b/node_modules/chai/lib/chai/utils/getEnumerableProperties.js new file mode 100644 index 000000000..a84252cfd --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getEnumerableProperties.js @@ -0,0 +1,26 @@ +/*! + * Chai - getEnumerableProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getEnumerableProperties(object) + * + * This allows the retrieval of enumerable property names of an object, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getEnumerableProperties + * @api public + */ + +module.exports = function getEnumerableProperties(object) { + var result = []; + for (var name in object) { + result.push(name); + } + return result; +}; diff --git a/node_modules/chai/lib/chai/utils/getMessage.js b/node_modules/chai/lib/chai/utils/getMessage.js new file mode 100644 index 000000000..1c9744feb --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getMessage.js @@ -0,0 +1,51 @@ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , inspect = require('./inspect') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function getMessage(obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; diff --git a/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js b/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js new file mode 100644 index 000000000..93a609e9d --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOwnEnumerableProperties.js @@ -0,0 +1,29 @@ +/*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/** + * ### .getOwnEnumerableProperties(object) + * + * This allows the retrieval of directly-owned enumerable property names and + * symbols of an object. This function is necessary because Object.keys only + * returns enumerable property names, not enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerableProperties + * @api public + */ + +module.exports = function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); +}; diff --git a/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js b/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js new file mode 100644 index 000000000..823c6b7aa --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getOwnEnumerablePropertySymbols.js @@ -0,0 +1,27 @@ +/*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getOwnEnumerablePropertySymbols(object) + * + * This allows the retrieval of directly-owned enumerable property symbols of an + * object. This function is necessary because Object.getOwnPropertySymbols + * returns both enumerable and non-enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerablePropertySymbols + * @api public + */ + +module.exports = function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== 'function') return []; + + return Object.getOwnPropertySymbols(obj).filter(function (sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); +}; diff --git a/node_modules/chai/lib/chai/utils/getProperties.js b/node_modules/chai/lib/chai/utils/getProperties.js new file mode 100644 index 000000000..ccf9631ab --- /dev/null +++ b/node_modules/chai/lib/chai/utils/getProperties.js @@ -0,0 +1,36 @@ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; diff --git a/node_modules/chai/lib/chai/utils/index.js b/node_modules/chai/lib/chai/utils/index.js new file mode 100644 index 000000000..d4f329c75 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/index.js @@ -0,0 +1,172 @@ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Dependencies that are used for multiple exports are required here only once + */ + +var pathval = require('pathval'); + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path info + */ + +exports.getPathInfo = pathval.getPathInfo; + +/*! + * Check if a property exists + */ + +exports.hasProperty = pathval.hasProperty; + +/*! + * Function name + */ + +exports.getName = require('get-func-name'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); + +/*! + * Compare by inspect method + */ + +exports.compareByInspect = require('./compareByInspect'); + +/*! + * Get own enumerable property symbols method + */ + +exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/*! + * Get own enumerable properties method + */ + +exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties'); + +/*! + * Checks error against a given set of criteria + */ + +exports.checkError = require('check-error'); + +/*! + * Proxify util + */ + +exports.proxify = require('./proxify'); + +/*! + * addLengthGuard util + */ + +exports.addLengthGuard = require('./addLengthGuard'); + +/*! + * isProxyEnabled helper + */ + +exports.isProxyEnabled = require('./isProxyEnabled'); + +/*! + * isNaN method + */ + +exports.isNaN = require('./isNaN'); diff --git a/node_modules/chai/lib/chai/utils/inspect.js b/node_modules/chai/lib/chai/utils/inspect.js new file mode 100644 index 000000000..3cf5dcef6 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/inspect.js @@ -0,0 +1,383 @@ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('get-func-name'); +var getProperties = require('./getProperties'); +var getEnumerableProperties = require('./getEnumerableProperties'); +var config = require('../config'); + +module.exports = inspect; + +/** + * ### .inspect(obj, [showHidden], [depth], [colors]) + * + * Echoes the value of a value. Tries to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. Default is false. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var ctx = { + showHidden: showHidden, + seen: [], + stylize: function (str) { return str; } + }; + return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); +} + +// Returns true if object is a DOM element. +var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + 'nodeType' in object && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } +}; + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (typeof ret !== 'string') { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // If this is a DOM element, try to get the outer HTML. + if (isDOMElement(value)) { + if ('outerHTML' in value) { + return value.outerHTML; + // This value does not have an outerHTML attribute, + // it could still be an XML element + } else { + // Attempt to serialize it + try { + if (document.xmlVersion) { + var xmlSerializer = new XMLSerializer(); + return xmlSerializer.serializeToString(value); + } else { + // Firefox 11- do not support outerHTML + // It does, however, support innerHTML + // Use the following to render the element + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + + container.appendChild(value.cloneNode(false)); + var html = container.innerHTML + .replace('><', '>' + value.innerHTML + '<'); + container.innerHTML = ''; + return html; + } + } catch (err) { + // This could be a non-native DOM implementation, + // continue with the normal flow: + // printing the element as if it is an object. + } + } + } + + // Look up the keys of the object. + var visibleKeys = getEnumerableProperties(value); + var keys = ctx.showHidden ? getProperties(value) : visibleKeys; + + var name, nameSuffix; + + // Some type of object without properties can be shortcutted. + // In IE, errors have a single `stack` property, or if they are vanilla `Error`, + // a `stack` plus `description` property; ignore those for consistency. + if (keys.length === 0 || (isError(value) && ( + (keys.length === 1 && keys[0] === 'stack') || + (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') + ))) { + if (typeof value === 'function') { + name = getName(value); + nameSuffix = name ? ': ' + name : ''; + return ctx.stylize('[Function' + nameSuffix + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '' + , array = false + , typedArray = false + , braces = ['{', '}']; + + if (isTypedArray(value)) { + typedArray = true; + braces = ['[', ']']; + } + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + name = getName(value); + nameSuffix = name ? ': ' + name : ''; + base = ' [Function' + nameSuffix + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + return formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else if (typedArray) { + return formatTypedArray(value); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + switch (typeof value) { + case 'undefined': + return ctx.stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + + case 'number': + if (value === 0 && (1/value) === -Infinity) { + return ctx.stylize('-0', 'number'); + } + return ctx.stylize('' + value, 'number'); + + case 'boolean': + return ctx.stylize('' + value, 'boolean'); + + case 'symbol': + return ctx.stylize(value.toString(), 'symbol'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return ctx.stylize('null', 'null'); + } +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (Object.prototype.hasOwnProperty.call(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + +function formatTypedArray(value) { + var str = '[ '; + + for (var i = 0; i < value.length; ++i) { + if (str.length >= config.truncateThreshold - 7) { + str += '...'; + break; + } + str += value[i] + ', '; + } + str += ' ]'; + + // Removing trailing `, ` if the array was not truncated + if (str.indexOf(', ]') !== -1) { + str = str.replace(', ]', ' ]'); + } + + return str; +} + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name; + var propDescriptor = Object.getOwnPropertyDescriptor(value, key); + var str; + + if (propDescriptor) { + if (propDescriptor.get) { + if (propDescriptor.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (propDescriptor.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + } + if (visibleKeys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = formatValue(ctx, value[key], null); + } else { + str = formatValue(ctx, value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function isTypedArray(ar) { + // Unfortunately there's no way to check if an object is a TypedArray + // We have to check if it's one of these types + return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar))); +} + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && objectToString(ar) === '[object Array]'); +} + +function isRegExp(re) { + return typeof re === 'object' && objectToString(re) === '[object RegExp]'; +} + +function isDate(d) { + return typeof d === 'object' && objectToString(d) === '[object Date]'; +} + +function isError(e) { + return typeof e === 'object' && objectToString(e) === '[object Error]'; +} + +function objectToString(o) { + return Object.prototype.toString.call(o); +} diff --git a/node_modules/chai/lib/chai/utils/isNaN.js b/node_modules/chai/lib/chai/utils/isNaN.js new file mode 100644 index 000000000..d64f7f4aa --- /dev/null +++ b/node_modules/chai/lib/chai/utils/isNaN.js @@ -0,0 +1,26 @@ +/*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani + * MIT Licensed + */ + +/** + * ### .isNaN(value) + * + * Checks if the given value is NaN or not. + * + * utils.isNaN(NaN); // true + * + * @param {Value} The value which has to be checked if it is NaN + * @name isNaN + * @api private + */ + +function isNaN(value) { + // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number + // section's NOTE. + return value !== value; +} + +// If ECMAScript 6's Number.isNaN is present, prefer that. +module.exports = Number.isNaN || isNaN; diff --git a/node_modules/chai/lib/chai/utils/isProxyEnabled.js b/node_modules/chai/lib/chai/utils/isProxyEnabled.js new file mode 100644 index 000000000..aa17dfa82 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/isProxyEnabled.js @@ -0,0 +1,24 @@ +var config = require('../config'); + +/*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .isProxyEnabled() + * + * Helper function to check if Chai's proxy protection feature is enabled. If + * proxies are unsupported or disabled via the user's Chai config, then return + * false. Otherwise, return true. + * + * @namespace Utils + * @name isProxyEnabled + */ + +module.exports = function isProxyEnabled() { + return config.useProxy && + typeof Proxy !== 'undefined' && + typeof Reflect !== 'undefined'; +}; diff --git a/node_modules/chai/lib/chai/utils/objDisplay.js b/node_modules/chai/lib/chai/utils/objDisplay.js new file mode 100644 index 000000000..32eacfa70 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/objDisplay.js @@ -0,0 +1,50 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay(object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function objDisplay(obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; diff --git a/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js b/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js new file mode 100644 index 000000000..3ca922492 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js @@ -0,0 +1,69 @@ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) + * + * Overwites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.lengthOf(3); + * expect(myFoo).to.have.lengthOf.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { + var result = chainingBehavior(_chainingBehavior).call(this); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function overwritingChainableMethodWrapper() { + var result = method(_method).apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; +}; diff --git a/node_modules/chai/lib/chai/utils/overwriteMethod.js b/node_modules/chai/lib/chai/utils/overwriteMethod.js new file mode 100644 index 000000000..f77a4f493 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteMethod.js @@ -0,0 +1,92 @@ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteMethod(ctx, name, fn) + * + * Overwites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function overwriteMethod(ctx, name, method) { + var _method = ctx[name] + , _super = function () { + throw new Error(name + ' is not a function'); + }; + + if (_method && 'function' === typeof _method) + _super = _method; + + var overwritingMethodWrapper = function () { + // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this + // function to be the starting point for removing implementation frames from + // the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingMethodWrapper); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion + // from changing the `ssfi` flag. By this point, the `ssfi` flag is already + // set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = method(_super).apply(this, arguments); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); +}; diff --git a/node_modules/chai/lib/chai/utils/overwriteProperty.js b/node_modules/chai/lib/chai/utils/overwriteProperty.js new file mode 100644 index 000000000..82ed3c876 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/overwriteProperty.js @@ -0,0 +1,92 @@ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteProperty(ctx, name, fn) + * + * Overwites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function overwriteProperty(ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function overwritingPropertyGetter() { + // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this + // function to be the starting point for removing implementation frames + // from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingPropertyGetter); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten + // assertion from changing the `ssfi` flag. By this point, the `ssfi` + // flag is already set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = getter(_super).call(this); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; diff --git a/node_modules/chai/lib/chai/utils/proxify.js b/node_modules/chai/lib/chai/utils/proxify.js new file mode 100644 index 000000000..2b3b0203d --- /dev/null +++ b/node_modules/chai/lib/chai/utils/proxify.js @@ -0,0 +1,125 @@ +var config = require('../config'); +var flag = require('./flag'); +var getProperties = require('./getProperties'); +var isProxyEnabled = require('./isProxyEnabled'); + +/*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .proxify(object) + * + * Return a proxy of given object that throws an error when a non-existent + * property is read. By default, the root cause is assumed to be a misspelled + * property, and thus an attempt is made to offer a reasonable suggestion from + * the list of existing properties. However, if a nonChainableMethodName is + * provided, then the root cause is instead a failure to invoke a non-chainable + * method prior to reading the non-existent property. + * + * If proxies are unsupported or disabled via the user's Chai config, then + * return object without modification. + * + * @param {Object} obj + * @param {String} nonChainableMethodName + * @namespace Utils + * @name proxify + */ + +var builtins = ['__flags', '__methods', '_obj', 'assert']; + +module.exports = function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) return obj; + + return new Proxy(obj, { + get: function proxyGetter(target, property) { + // This check is here because we should not throw errors on Symbol properties + // such as `Symbol.toStringTag`. + // The values for which an error should be thrown can be configured using + // the `config.proxyExcludedKeys` setting. + if (typeof property === 'string' && + config.proxyExcludedKeys.indexOf(property) === -1 && + !Reflect.has(target, property)) { + // Special message for invalid property access of non-chainable methods. + if (nonChainableMethodName) { + throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' + + property + '. See docs for proper usage of "' + + nonChainableMethodName + '".'); + } + + var orderedProperties = getProperties(target).filter(function(property) { + return !Object.prototype.hasOwnProperty(property) && + builtins.indexOf(property) === -1; + }).sort(function(a, b) { + return stringDistance(property, a) - stringDistance(property, b); + }); + + if (orderedProperties.length && + stringDistance(orderedProperties[0], property) < 4) { + // If the property is reasonably close to an existing Chai property, + // suggest that property to the user. + throw Error('Invalid Chai property: ' + property + + '. Did you mean "' + orderedProperties[0] + '"?'); + } else { + throw Error('Invalid Chai property: ' + property); + } + } + + // Use this proxy getter as the starting point for removing implementation + // frames from the stack trace of a failed assertion. For property + // assertions, this prevents the proxy getter from showing up in the stack + // trace since it's invoked before the property getter. For method and + // chainable method assertions, this flag will end up getting changed to + // the method wrapper, which is good since this frame will no longer be in + // the stack once the method is invoked. Note that Chai builtin assertion + // properties such as `__flags` are skipped since this is only meant to + // capture the starting point of an assertion. This step is also skipped + // if the `lockSsfi` flag is set, thus indicating that this assertion is + // being called from within another assertion. In that case, the `ssfi` + // flag is already set to the outer assertion's starting point. + if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { + flag(target, 'ssfi', proxyGetter); + } + + return Reflect.get(target, property); + } + }); +}; + +/** + * # stringDistance(strA, strB) + * Return the Levenshtein distance between two strings. + * @param {string} strA + * @param {string} strB + * @return {number} the string distance between strA and strB + * @api private + */ + +function stringDistance(strA, strB, memo) { + if (!memo) { + // `memo` is a two-dimensional array containing a cache of distances + // memo[i][j] is the distance between strA.slice(0, i) and + // strB.slice(0, j). + memo = []; + for (var i = 0; i <= strA.length; i++) { + memo[i] = []; + } + } + + if (!memo[strA.length] || !memo[strA.length][strB.length]) { + if (strA.length === 0 || strB.length === 0) { + memo[strA.length][strB.length] = Math.max(strA.length, strB.length); + } else { + memo[strA.length][strB.length] = Math.min( + stringDistance(strA.slice(0, -1), strB, memo) + 1, + stringDistance(strA, strB.slice(0, -1), memo) + 1, + stringDistance(strA.slice(0, -1), strB.slice(0, -1), memo) + + (strA.slice(-1) === strB.slice(-1) ? 0 : 1) + ); + } + } + + return memo[strA.length][strB.length]; +} diff --git a/node_modules/chai/lib/chai/utils/test.js b/node_modules/chai/lib/chai/utils/test.js new file mode 100644 index 000000000..6c4fc4a69 --- /dev/null +++ b/node_modules/chai/lib/chai/utils/test.js @@ -0,0 +1,28 @@ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag'); + +/** + * ### .test(object, expression) + * + * Test and object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function test(obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; diff --git a/node_modules/chai/lib/chai/utils/transferFlags.js b/node_modules/chai/lib/chai/utils/transferFlags.js new file mode 100644 index 000000000..634e0537a --- /dev/null +++ b/node_modules/chai/lib/chai/utils/transferFlags.js @@ -0,0 +1,45 @@ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, `lockSsfi`, + * and `message`) will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAsseriton = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function transferFlags(assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; diff --git a/node_modules/chai/package.json b/node_modules/chai/package.json new file mode 100644 index 000000000..bb2000ec3 --- /dev/null +++ b/node_modules/chai/package.json @@ -0,0 +1,96 @@ +{ + "_from": "chai", + "_id": "chai@4.1.2", + "_inBundle": false, + "_integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "_location": "/chai", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "chai", + "name": "chai", + "escapedName": "chai", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#DEV:/", + "#USER" + ], + "_resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "_shasum": "0f64584ba642f0f2ace2806279f4f06ca23ad73c", + "_spec": "chai", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge", + "author": { + "name": "Jake Luer", + "email": "jake@alogicalparadox.com" + }, + "bugs": { + "url": "https://github.com/chaijs/chai/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "Jake Luer", + "email": "jake@alogicalparadox.com" + }, + { + "name": "Domenic Denicola", + "email": "domenic@domenicdenicola.com", + "url": "http://domenicdenicola.com" + }, + { + "name": "Veselin Todorov", + "email": "hi@vesln.com" + }, + { + "name": "John Firebaugh", + "email": "john.firebaugh@gmail.com" + } + ], + "dependencies": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + }, + "deprecated": false, + "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + "devDependencies": { + "browserify": "^14.4.0", + "bump-cli": "^1.1.3", + "istanbul": "^0.4.3", + "karma": "^1.0.0", + "karma-firefox-launcher": "^1.0.0", + "karma-mocha": "^1.0.1", + "karma-phantomjs-launcher": "^1.0.0", + "karma-sauce-launcher": "^1.0.0", + "mocha": "^3.0.0" + }, + "engines": { + "node": ">=4" + }, + "homepage": "http://chaijs.com", + "keywords": [ + "test", + "assertion", + "assert", + "testing", + "chai" + ], + "license": "MIT", + "main": "./index", + "name": "chai", + "repository": { + "type": "git", + "url": "git+https://github.com/chaijs/chai.git" + }, + "scripts": { + "test": "make test" + }, + "version": "4.1.2" +} diff --git a/node_modules/chai/register-assert.js b/node_modules/chai/register-assert.js new file mode 100644 index 000000000..f80cb4ded --- /dev/null +++ b/node_modules/chai/register-assert.js @@ -0,0 +1 @@ +global.assert = require('./').assert; diff --git a/node_modules/chai/register-expect.js b/node_modules/chai/register-expect.js new file mode 100644 index 000000000..f905c3a20 --- /dev/null +++ b/node_modules/chai/register-expect.js @@ -0,0 +1 @@ +global.expect = require('./').expect; diff --git a/node_modules/chai/register-should.js b/node_modules/chai/register-should.js new file mode 100644 index 000000000..5dab96fc5 --- /dev/null +++ b/node_modules/chai/register-should.js @@ -0,0 +1 @@ +global.should = require('./').should(); diff --git a/node_modules/chai/sauce.browsers.js b/node_modules/chai/sauce.browsers.js new file mode 100644 index 000000000..aa04ea8ff --- /dev/null +++ b/node_modules/chai/sauce.browsers.js @@ -0,0 +1,111 @@ + +/*! + * Chrome + */ + +exports['SL_Chrome'] = { + base: 'SauceLabs' + , browserName: 'chrome' +}; + +/*! + * Firefox + */ + + exports['SL_Firefox'] = { + base: 'SauceLabs' + , browserName: 'firefox' + }; + + exports['SL_Firefox_ESR'] = { + base: 'SauceLabs' + , browserName: 'firefox' + , version: 38 + }; + +/*! + * Opera + */ + +exports['SL_Opera'] = { + base: 'SauceLabs' + , browserName: 'opera' +}; + +/*! + * Internet Explorer + */ + +exports['SL_IE'] = { + base: 'SauceLabs' + , browserName: 'internet explorer' +}; + +exports['SL_IE_Old'] = { + base: 'SauceLabs' + , browserName: 'internet explorer' + , version: 10 +}; + +exports['SL_Edge'] = { + base: 'SauceLabs' + , browserName: 'microsoftedge' +}; + +/*! + * Safari + */ + +exports['SL_Safari'] = { + base: 'SauceLabs' + , browserName: 'safari' + , platform: 'Mac 10.11' +}; + +/*! + * iPhone + */ + +/*! + * TODO: These take forever to boot or shut down. Causes timeout. + * + +exports['SL_iPhone_6'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.8' + , version: '6' +}; + +exports['SL_iPhone_5-1'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.8' + , version: '5.1' +}; + +exports['SL_iPhone_5'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.6' + , version: '5' +}; + +*/ + +/*! + * Android + */ + +/*! + * TODO: fails because of error serialization + * + +exports['SL_Android_4'] = { + base: 'SauceLabs' + , browserName: 'android' + , platform: 'Linux' + , version: '4' +}; + +*/ diff --git a/node_modules/chalk/index.js b/node_modules/chalk/index.js new file mode 100644 index 000000000..ac1f16820 --- /dev/null +++ b/node_modules/chalk/index.js @@ -0,0 +1,95 @@ +'use strict'; +var escapeStringRegexp = require('escape-string-regexp'); +var ansiStyles = require('ansi-styles'); +var stripAnsi = require('strip-ansi'); +var hasAnsi = require('has-ansi'); +var supportsColor = require('supports-color'); +var defineProps = Object.defineProperties; +var chalk = module.exports; + +function build(_styles) { + var builder = function builder() { + return applyStyle.apply(builder, arguments); + }; + builder._styles = _styles; + // __proto__ is used because we must return a function, but there is + // no way to create a function with a different prototype. + builder.__proto__ = proto; + return builder; +} + +var styles = (function () { + var ret = {}; + + ansiStyles.grey = ansiStyles.gray; + + Object.keys(ansiStyles).forEach(function (key) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + + ret[key] = { + get: function () { + return build(this._styles.concat(key)); + } + }; + }); + + return ret; +})(); + +var proto = defineProps(function chalk() {}, styles); + +function applyStyle() { + // support varags, but simply cast to string in case there's only one arg + var args = arguments; + var argsLen = args.length; + var str = argsLen !== 0 && String(arguments[0]); + if (argsLen > 1) { + // don't slice `arguments`, it prevents v8 optimizations + for (var a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + + if (!chalk.enabled || !str) { + return str; + } + + /*jshint validthis: true*/ + var nestedStyles = this._styles; + + for (var i = 0; i < nestedStyles.length; i++) { + var code = ansiStyles[nestedStyles[i]]; + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; + } + + return str; +} + +function init() { + var ret = {}; + + Object.keys(styles).forEach(function (name) { + ret[name] = { + get: function () { + return build([name]); + } + }; + }); + + return ret; +} + +defineProps(chalk, init()); + +chalk.styles = ansiStyles; +chalk.hasColor = hasAnsi; +chalk.stripColor = stripAnsi; +chalk.supportsColor = supportsColor; + +// detect mode if not set manually +if (chalk.enabled === undefined) { + chalk.enabled = chalk.supportsColor; +} diff --git a/node_modules/chalk/node_modules/.bin/supports-color b/node_modules/chalk/node_modules/.bin/supports-color new file mode 120000 index 000000000..af0f05efe --- /dev/null +++ b/node_modules/chalk/node_modules/.bin/supports-color @@ -0,0 +1 @@ +../supports-color/cli.js \ No newline at end of file diff --git a/node_modules/chalk/node_modules/supports-color/cli.js b/node_modules/chalk/node_modules/supports-color/cli.js new file mode 100755 index 000000000..0617971e6 --- /dev/null +++ b/node_modules/chalk/node_modules/supports-color/cli.js @@ -0,0 +1,28 @@ +#!/usr/bin/env node +'use strict'; +var pkg = require('./package.json'); +var supportsColor = require('./'); +var input = process.argv[2]; + +function help() { + console.log([ + pkg.description, + '', + 'Usage', + ' $ supports-color', + '', + 'Exits with code 0 if color is supported and 1 if not' + ].join('\n')); +} + +if (!input || process.argv.indexOf('--help') !== -1) { + help(); + return; +} + +if (process.argv.indexOf('--version') !== -1) { + console.log(pkg.version); + return; +} + +process.exit(supportsColor ? 0 : 1); diff --git a/node_modules/chalk/node_modules/supports-color/index.js b/node_modules/chalk/node_modules/supports-color/index.js new file mode 100644 index 000000000..092d0baef --- /dev/null +++ b/node_modules/chalk/node_modules/supports-color/index.js @@ -0,0 +1,32 @@ +'use strict'; +module.exports = (function () { + if (process.argv.indexOf('--no-color') !== -1) { + return false; + } + + if (process.argv.indexOf('--color') !== -1) { + return true; + } + + if (process.stdout && !process.stdout.isTTY) { + return false; + } + + if (process.platform === 'win32') { + return true; + } + + if ('COLORTERM' in process.env) { + return true; + } + + if (process.env.TERM === 'dumb') { + return false; + } + + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { + return true; + } + + return false; +})(); diff --git a/node_modules/chalk/node_modules/supports-color/package.json b/node_modules/chalk/node_modules/supports-color/package.json new file mode 100644 index 000000000..0bb4ebeed --- /dev/null +++ b/node_modules/chalk/node_modules/supports-color/package.json @@ -0,0 +1,82 @@ +{ + "_from": "supports-color@^0.2.0", + "_id": "supports-color@0.2.0", + "_inBundle": false, + "_integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "_location": "/chalk/supports-color", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "supports-color@^0.2.0", + "name": "supports-color", + "escapedName": "supports-color", + "rawSpec": "^0.2.0", + "saveSpec": null, + "fetchSpec": "^0.2.0" + }, + "_requiredBy": [ + "/chalk" + ], + "_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "_shasum": "d92de2694eb3f67323973d7ae3d8b55b4c22190a", + "_spec": "supports-color@^0.2.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bin": { + "supports-color": "cli.js" + }, + "bugs": { + "url": "https://github.com/sindresorhus/supports-color/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Detect whether a terminal supports color", + "devDependencies": { + "mocha": "*" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "cli.js" + ], + "homepage": "https://github.com/sindresorhus/supports-color#readme", + "keywords": [ + "cli", + "bin", + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "ansi", + "styles", + "tty", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "support", + "supports", + "capability", + "detect" + ], + "license": "MIT", + "name": "supports-color", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/supports-color.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "0.2.0" +} diff --git a/node_modules/chalk/node_modules/supports-color/readme.md b/node_modules/chalk/node_modules/supports-color/readme.md new file mode 100644 index 000000000..7f07e5fb0 --- /dev/null +++ b/node_modules/chalk/node_modules/supports-color/readme.md @@ -0,0 +1,44 @@ +# supports-color [![Build Status](https://travis-ci.org/sindresorhus/supports-color.svg?branch=master)](https://travis-ci.org/sindresorhus/supports-color) + +> Detect whether a terminal supports color + + +## Install + +```sh +$ npm install --save supports-color +``` + + +## Usage + +```js +var supportsColor = require('supports-color'); + +if (supportsColor) { + console.log('Terminal supports color'); +} +``` + +It obeys the `--color` and `--no-color` CLI flags. + + +## CLI + +```sh +$ npm install --global supports-color +``` + +```sh +$ supports-color --help + +Usage + $ supports-color + +# Exits with code 0 if color is supported and 1 if not +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/chalk/package.json b/node_modules/chalk/package.json new file mode 100644 index 000000000..22de722b5 --- /dev/null +++ b/node_modules/chalk/package.json @@ -0,0 +1,92 @@ +{ + "_from": "chalk@^0.5.1", + "_id": "chalk@0.5.1", + "_inBundle": false, + "_integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "_location": "/chalk", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "chalk@^0.5.1", + "name": "chalk", + "escapedName": "chalk", + "rawSpec": "^0.5.1", + "saveSpec": null, + "fetchSpec": "^0.5.1" + }, + "_requiredBy": [ + "/pryjs" + ], + "_resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "_shasum": "663b3a648b68b55d04690d49167aa837858f2174", + "_spec": "chalk@^0.5.1", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/pryjs", + "bugs": { + "url": "https://github.com/sindresorhus/chalk/issues" + }, + "bundleDependencies": false, + "dependencies": { + "ansi-styles": "^1.1.0", + "escape-string-regexp": "^1.0.0", + "has-ansi": "^0.1.0", + "strip-ansi": "^0.3.0", + "supports-color": "^0.2.0" + }, + "deprecated": false, + "description": "Terminal string styling done right. Created because the `colors` module does some really horrible things.", + "devDependencies": { + "matcha": "^0.5.0", + "mocha": "*" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/chalk#readme", + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "ansi", + "styles", + "tty", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "license": "MIT", + "maintainers": [ + { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + { + "name": "Joshua Appelman", + "email": "joshua@jbna.nl" + } + ], + "name": "chalk", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/chalk.git" + }, + "scripts": { + "bench": "matcha benchmark.js", + "test": "mocha" + }, + "version": "0.5.1" +} diff --git a/node_modules/chalk/readme.md b/node_modules/chalk/readme.md new file mode 100644 index 000000000..239c791f8 --- /dev/null +++ b/node_modules/chalk/readme.md @@ -0,0 +1,175 @@ +# chalk + +> Terminal string styling done right + +[![Build Status](https://travis-ci.org/sindresorhus/chalk.svg?branch=master)](https://travis-ci.org/sindresorhus/chalk) +![](http://img.shields.io/badge/unicorn-approved-ff69b4.svg) + +[colors.js](https://github.com/Marak/colors.js) is currently the most popular string styling module, but it has serious deficiencies like extending String.prototype which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough. + +**Chalk is a clean and focused alternative.** + +![screenshot](https://github.com/sindresorhus/ansi-styles/raw/master/screenshot.png) + + +## Why + +- Highly performant +- Doesn't extend String.prototype +- Expressive API +- Ability to nest styles +- Clean and focused +- Auto-detects color support +- Actively maintained +- [Used by 1000+ modules](https://npmjs.org/browse/depended/chalk) + + +## Install + +```sh +$ npm install --save chalk +``` + + +## Usage + +Chalk comes with an easy to use composable API where you just chain and nest the styles you want. + +```js +var chalk = require('chalk'); + +// style a string +console.log( chalk.blue('Hello world!') ); + +// combine styled and normal strings +console.log( chalk.blue('Hello'), 'World' + chalk.red('!') ); + +// compose multiple styles using the chainable API +console.log( chalk.blue.bgRed.bold('Hello world!') ); + +// pass in multiple arguments +console.log( chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz') ); + +// nest styles +console.log( chalk.red('Hello', chalk.underline.bgBlue('world') + '!') ); + +// nest styles of the same type even (color, underline, background) +console.log( chalk.green('I am a green line ' + chalk.blue('with a blue substring') + ' that becomes green again!') ); +``` + +Easily define your own themes. + +```js +var chalk = require('chalk'); +var error = chalk.bold.red; +console.log(error('Error!')); +``` + +Take advantage of console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data). + +```js +var name = 'Sindre'; +console.log(chalk.green('Hello %s'), name); +//=> Hello Sindre +``` + + +## API + +### chalk.` +{% endif %} diff --git a/node_modules/pryjs/docs/_layouts/default.html b/node_modules/pryjs/docs/_layouts/default.html new file mode 100644 index 000000000..40c1aea6c --- /dev/null +++ b/node_modules/pryjs/docs/_layouts/default.html @@ -0,0 +1,11 @@ + + + {% include head.html %} + + {% include header.html %} +
+ {{ content }} +
+ {% include footer.html %} + + diff --git a/node_modules/pryjs/docs/_layouts/home.html b/node_modules/pryjs/docs/_layouts/home.html new file mode 100644 index 000000000..804d11422 --- /dev/null +++ b/node_modules/pryjs/docs/_layouts/home.html @@ -0,0 +1,14 @@ +--- +layout: default +--- +
+ {% if site.theme.header_text %} +
+ {{ site.theme.header_text }} +
+ {% endif %} +
+ {{ content }} +
+
diff --git a/node_modules/pryjs/docs/_layouts/page.html b/node_modules/pryjs/docs/_layouts/page.html new file mode 100644 index 000000000..44104124a --- /dev/null +++ b/node_modules/pryjs/docs/_layouts/page.html @@ -0,0 +1,9 @@ +--- +layout: default +--- +
+
+

{{ page.title }}

+
+
{{ content }}
+
diff --git a/node_modules/pryjs/docs/_layouts/post.html b/node_modules/pryjs/docs/_layouts/post.html new file mode 100644 index 000000000..941592b56 --- /dev/null +++ b/node_modules/pryjs/docs/_layouts/post.html @@ -0,0 +1,42 @@ +--- +layout: default +--- +
+
+

{{ page.title }}

+

+ {{ page.date | date: "%B %-d, %Y" }} + {% if page.author %} - {{ page.author }}{% endif %} +

+
+
{{ content }}
+
+ + +{% if site.theme.post_navigation %} +
+ {% if page.previous.url %} + + {% endif %} + {% if page.next.url %} + + {% endif %} +
+{% endif %} + + +{% if site.theme.disqus_shortname %} +
+ {% include disqus.html %} +
+{% endif %} diff --git a/node_modules/pryjs/docs/_sass/base/_global.scss b/node_modules/pryjs/docs/_sass/base/_global.scss new file mode 100644 index 000000000..5348ef265 --- /dev/null +++ b/node_modules/pryjs/docs/_sass/base/_global.scss @@ -0,0 +1,123 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} +figure { + margin: 0; +} +// For correct line number width in Github Gists +.gist table tbody tr td { + box-sizing: content-box; +} +html { + background: $background-color; +} + +// Typography +::selection { + background: $selection-color; +} +::-moz-selection { + background: $selection-color; +} +body { + color: $text-color; + font-family: $font-family-main; + font-size: $font-size; + word-wrap: break-word; +} +h1, h2, h3, h4, h5, h6 { + font-family: $font-family-headings; + line-height: 1.3; + margin: 0.67em 0; + a { + color: $text-color; + } +} +h1 { + font-size: 2.5em; +} +h2 { + font-size: 2em; +} +h3 { + font-size: 1.5em; +} +h4 { + font-size: 1.15em; +} +blockquote { + border-left: 2px solid; + padding: 1em 1em; +} +blockquote p:last-child, +footer p:last-child { + margin-bottom: 0; +} +table { + table-layout:fixed; + width:100%; + word-wrap:break-word; + @media (max-width: 1100px) { + overflow-x: scroll; + display: inline-block; + } +} +td, +th { + padding: 0.5em 1em; + border: 1px solid $border-color; + text-align: left; +} +table, +dl, +blockquote, +code, +kbd, +pre, +samp { + margin: 1em 0; +} +dt { + font-weight: bold; +} +dd { + margin-left: 2em; +} +p, ol, ul, dl, .math-display { + line-height: 1.5; + margin-bottom: 1em; +} +.math-display { + display: inline-block; + width: 100%; +} +ol, ul { + list-style-position: inside; +} +hr { + border: 0; + border-top: 1px solid $border-color; + border-bottom: 1px solid #fff; + margin: 1em 0; +} +a { + color: $link-color; + text-decoration: none; +} +.nav { + list-style: none; + margin: 0; + padding: 0; +} +// Responsive media +iframe, img, embed, object, video { + max-width: 100%; +} +img[align=left] { + margin-right: 3%; +} +img[align=right] { + margin-left: 3%; +} diff --git a/node_modules/pryjs/docs/_sass/base/_utility.scss b/node_modules/pryjs/docs/_sass/base/_utility.scss new file mode 100644 index 000000000..0d7f0a818 --- /dev/null +++ b/node_modules/pryjs/docs/_sass/base/_utility.scss @@ -0,0 +1,35 @@ +// Mix-ins +%padding-small { + padding: $padding-x-small $padding-x-small * 2; + @media (max-width: 1000px) { + padding: $padding-x-small $padding-x-small; + } +} +%padding-regular { + padding: $padding-small $padding-large; + @media (max-width: 1000px) { + padding: $padding-small * 1.5 $padding-large / 1.6; + } +} +%link-hover { + text-decoration: underline; + color: darken($link-color, 15%); +} +// Buttons +.button { + border-radius: 0.3em; + border: 1px solid; + display: inline-block; + margin: 1em 0; + padding: 0.5em 0.75em; +} +a.button:hover { + background: $link-color; + border: 1px solid $link-color; + color: $background-color; + text-decoration: none; +} +// States +.disabled { + opacity: 0.7; +} diff --git a/node_modules/pryjs/docs/_sass/base/_variables.scss b/node_modules/pryjs/docs/_sass/base/_variables.scss new file mode 100644 index 000000000..dcc8935e1 --- /dev/null +++ b/node_modules/pryjs/docs/_sass/base/_variables.scss @@ -0,0 +1,30 @@ +// Typography +$font-family-main: 'Source Sans Pro', Helvetica, Arial, sans-serif; +$font-family-headings: 'Source Sans Pro', Helvetica, Arial, sans-serif; +$font-size: 1.25em; + +// Padding +$padding-large: 20%; +$padding-small: 5%; +$padding-x-small: 3%; + +// Brand colours +$brand-color: #fff; +$background-color: #fff; +$border-color: rgba(0, 0, 0, 0.1); // rgba recommended if using feature images + +// Typography colours +$text-color: #383838; +$link-color: #1ABC9C; +$selection-color: #D4D4D4; // visible when highlighting text + +// Header colours +$header-link-color: #383838; + +// Feature image for articles +$feature-image-text-color: #fff; +$feature-image-size: cover; // options include "cover", "contain", "auto" + +// Header description box +$header-desc-background-color: #F98752; +$header-desc-text-color: #FFF; diff --git a/node_modules/pryjs/docs/_sass/external/_reset.scss b/node_modules/pryjs/docs/_sass/external/_reset.scss new file mode 100644 index 000000000..458eea1ea --- /dev/null +++ b/node_modules/pryjs/docs/_sass/external/_reset.scss @@ -0,0 +1,427 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} diff --git a/node_modules/pryjs/docs/_sass/external/_syntax.scss b/node_modules/pryjs/docs/_sass/external/_syntax.scss new file mode 100644 index 000000000..fd6328632 --- /dev/null +++ b/node_modules/pryjs/docs/_sass/external/_syntax.scss @@ -0,0 +1,63 @@ +// pygments-css (https://github.com/richleland/pygments-css) + +.hll { background-color: #ffffcc } +.c { color: #999988; font-style: italic } /* Comment */ +.err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.k { color: #000000; font-weight: bold } /* Keyword */ +.o { color: #000000; font-weight: bold } /* Operator */ +.cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */ +.c1 { color: #999988; font-style: italic } /* Comment.Single */ +.cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.ge { color: #000000; font-style: italic } /* Generic.Emph */ +.gr { color: #aa0000 } /* Generic.Error */ +.gh { color: #999999 } /* Generic.Heading */ +.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.go { color: #888888 } /* Generic.Output */ +.gp { color: #555555 } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #aaaaaa } /* Generic.Subheading */ +.gt { color: #aa0000 } /* Generic.Traceback */ +.kc { color: #000000; font-weight: bold } /* Keyword.Constant */ +.kd { color: #000000; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #000000; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */ +.kr { color: #000000; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.m { color: #009999 } /* Literal.Number */ +.s { color: #d01040 } /* Literal.String */ +.na { color: #008080 } /* Name.Attribute */ +.nb { color: #0086B3 } /* Name.Builtin */ +.nc { color: #445588; font-weight: bold } /* Name.Class */ +.no { color: #008080 } /* Name.Constant */ +.nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */ +.ni { color: #800080 } /* Name.Entity */ +.ne { color: #990000; font-weight: bold } /* Name.Exception */ +.nf { color: #990000; font-weight: bold } /* Name.Function */ +.nl { color: #990000; font-weight: bold } /* Name.Label */ +.nn { color: #555555 } /* Name.Namespace */ +.nt { color: #000080 } /* Name.Tag */ +.nv { color: #008080 } /* Name.Variable */ +.ow { color: #000000; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mf { color: #009999 } /* Literal.Number.Float */ +.mh { color: #009999 } /* Literal.Number.Hex */ +.mi { color: #009999 } /* Literal.Number.Integer */ +.mo { color: #009999 } /* Literal.Number.Oct */ +.sb { color: #d01040 } /* Literal.String.Backtick */ +.sc { color: #d01040 } /* Literal.String.Char */ +.sd { color: #d01040 } /* Literal.String.Doc */ +.s2 { color: #d01040 } /* Literal.String.Double */ +.se { color: #d01040 } /* Literal.String.Escape */ +.sh { color: #d01040 } /* Literal.String.Heredoc */ +.si { color: #d01040 } /* Literal.String.Interpol */ +.sx { color: #d01040 } /* Literal.String.Other */ +.sr { color: #009926 } /* Literal.String.Regex */ +.s1 { color: #d01040 } /* Literal.String.Single */ +.ss { color: #990073 } /* Literal.String.Symbol */ +.bp { color: #999999 } /* Name.Builtin.Pseudo */ +.vc { color: #008080 } /* Name.Variable.Class */ +.vg { color: #008080 } /* Name.Variable.Global */ +.vi { color: #008080 } /* Name.Variable.Instance */ +.il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/node_modules/pryjs/docs/_sass/includes/_footer.scss b/node_modules/pryjs/docs/_sass/includes/_footer.scss new file mode 100644 index 000000000..36437049c --- /dev/null +++ b/node_modules/pryjs/docs/_sass/includes/_footer.scss @@ -0,0 +1,8 @@ +.site-footer { + @extend %padding-regular; + display: inline-block; + text-align: center; + width: 100%; + color: lighten($text-color, 30%); + font-size: 0.9em; +} diff --git a/node_modules/pryjs/docs/_sass/includes/_header.scss b/node_modules/pryjs/docs/_sass/includes/_header.scss new file mode 100644 index 000000000..4cec81b33 --- /dev/null +++ b/node_modules/pryjs/docs/_sass/includes/_header.scss @@ -0,0 +1,86 @@ +.site-header { + @extend %padding-small; + background: $brand-color; + border-bottom: 1px solid $border-color; + display: inline-block; + float: left; + width: 100%; + + a { + color: $header-link-color; + } + + .branding h1 { + text-indent: -99999px; + } + + .logo { + width: 200px; + float: left; + margin-top: -3px; + border-radius: 0.2em; + margin-right: 1em; + text-indent: -99999px; + } + + .site-title { + float: left; + font-weight: bold; + font-size: 1em; + line-height: 1.5; + } + + .site-nav { + ul { + margin: 0; + padding: 0; + list-style: none; + line-height: 1.5; + float: right; + text-align: right; + } + li { + display: inline; + float: left; + margin-right: 0.4em; + } + @media (max-width: 1100px) { + ul { + display: inline-block; + float: left; + padding-top: $padding-small; + text-align: left; + width: 100%; + } + } + } + .github-corner { + position: fixed; + top: 0; + right: 0; + &:hover .octo-arm { + animation: octocat-wave 560ms ease-in-out + } + } + @keyframes octocat-wave { + 0%, 100% { + transform: rotate(0) + } + 20%, + 60% { + transform: rotate(-25deg) + } + 40%, + 80% { + transform: rotate(10deg) + } + } + @media (max-width: 500px) { + .github-corner:hover .octo-arm { + animation: none + } + .github-corner .octo-arm { + animation: octocat-wave 560ms ease-in-out + } + } +} diff --git a/node_modules/pryjs/docs/_sass/layouts/_index.scss b/node_modules/pryjs/docs/_sass/layouts/_index.scss new file mode 100644 index 000000000..3d46e02b8 --- /dev/null +++ b/node_modules/pryjs/docs/_sass/layouts/_index.scss @@ -0,0 +1,45 @@ +// Header text feature +.call-out { + @extend %padding-regular; + display: inline-block; + width: 100%; + background-color:$header-desc-background-color; + background-size: cover; + font-size: 1.2em; + text-align: center; + color: $header-desc-text-color; + a { + color: yellow; + } +} +.call-out p:last-child { + margin-bottom: 0; +} +// Post listing +.posts { + .post-teaser { + @extend %padding-regular; + width: 100%; + margin-bottom: 0; + display: inline-block; + background-size: $feature-image-size; + border-bottom: 1px solid $border-color; + p a:hover { + @extend %link-hover; + } + } + .excerpt { + margin-top: 1em; + } +} +// Pagination +.pagination .button { + margin: 0 1.5em; + i { + vertical-align: middle; + } +} +.pagination { + padding: $padding-small $padding-large 0 $padding-large; + text-align: center; +} diff --git a/node_modules/pryjs/docs/_sass/layouts/_posts.scss b/node_modules/pryjs/docs/_sass/layouts/_posts.scss new file mode 100644 index 000000000..b64eb29e7 --- /dev/null +++ b/node_modules/pryjs/docs/_sass/layouts/_posts.scss @@ -0,0 +1,81 @@ +article, +.comments { + @extend %padding-regular; + border-bottom: 1px solid $border-color; + float: left; + width: 100%; +} +article { + header { + margin-bottom: 6%; + text-align: center; + } + a:hover { + @extend %link-hover; + } + .footnotes { + font-size: 0.9em; + } +} +header { + h1 { + margin: 0; + } + .meta { + color: rgba($text-color, .5); + font-size: 0.9em; + letter-spacing: 0.1em; + margin: 0; + text-transform: uppercase; + } +} +.feature-image { + padding: 0%; + .post-link { + color: $feature-image-text-color; + } + header { + color: $feature-image-text-color; + background-size: $feature-image-size; + margin-bottom: 0; + padding: $padding-large/2.5 $padding-large; + .meta { + color: rgba($feature-image-text-color, .7); + } + } + .post-content { + @extend %padding-regular; + } +} +// Post navigation +#post-nav { + width:100%; + border-bottom: 1px solid $border-color; + display: flex; + float: left; + + a, .page-title { + display: inline-block; + } + + .page-title { + font-size: 1.2em; + margin-bottom: 1em; + width: 100%; + } + + a { + padding: 2em 3em; + border: 1px solid rgba(255, 255, 255, 0); + text-align: center; + width: 50%; + } + a:hover { + @extend a.button:hover; + } + + i { + vertical-align: middle; + } +} + diff --git a/node_modules/pryjs/docs/css/main.scss b/node_modules/pryjs/docs/css/main.scss new file mode 100644 index 000000000..dd6c3a779 --- /dev/null +++ b/node_modules/pryjs/docs/css/main.scss @@ -0,0 +1,18 @@ +--- +--- +// External +@import 'external/reset'; +@import 'external/syntax'; + +// Base +@import 'base/variables'; +@import 'base/global'; +@import 'base/utility'; + +// Posts +@import 'layouts/posts'; +@import 'layouts/index'; + +// Partials +@import 'includes/header'; +@import 'includes/footer'; diff --git a/node_modules/pryjs/docs/favicon.ico b/node_modules/pryjs/docs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5614f69cb3fc1e9fa69af6a2742ba5b5bc155bef GIT binary patch literal 1150 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%0D}Go=4%Z$f)u>Nh3zIj=^x1yzUV#(Q&kX3l&k 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 LNkvXXu0mjfo*{+; literal 0 HcmV?d00001 diff --git a/node_modules/pryjs/docs/index.md b/node_modules/pryjs/docs/index.md new file mode 100644 index 000000000..cb44f3e54 --- /dev/null +++ b/node_modules/pryjs/docs/index.md @@ -0,0 +1,61 @@ +--- +layout: home +--- + +This offers many advantages over other debuggers. It allows you to see and write +in *CoffeeScript* or *JavaScript*, so you can debug in the language you wrote in. +It's easy to setup. Just a simple `npm install` and it's already working! The +tests run the examples! It uses +[Cucumber](https://www.npmjs.com/package/cucumber) to run the examples for all +of our tests, so you know they work! + +## Quick Start + +~~~ bash +npm install --save pryjs +~~~ + +### Usage + +Throw this beautiful snippet in the middle of your code: + +~~~ javascript +import pry from 'pryjs' +eval(pry.it) +~~~ + +~~~ javascript +pry = require('pryjs') +eval(pry.it) +~~~ + +You *MUST* name the variable `pry`. You are executing an anonymous function, and +this assumes the variable is named `pry` in your scope. This is so it can keep +prompting you. + +## Global Command + +~~~ bash +npm install -g pryjs +~~~ + +~~~ bash +pryjs +~~~ + +## Extra Commands + +While you are in the prompt there are a few things you might want to do: + +* `help` display all the available commands. +* `kill` completely stop the script. +* `mode` switch between javascript and coffeescript mode. Defaults to javascript. +* `play` play lines of code as if you had entered them. Accepts two integers: start and end. End defaults to start. +* `stop` will exit the pryjs prompt and continue through the app. +* `version` display the current version. +* `whereami` will show you exactly where you are in the code. Accepts two integers to replace the default 5 before and 5 after. +* `wtf` display the last caught exception. + +## Learn More + +There are more examples and information in the readme of the [GitHub Repo](https://github.com/blainesch/pry.js). diff --git a/node_modules/pryjs/docs/js/katex_init.js b/node_modules/pryjs/docs/js/katex_init.js new file mode 100644 index 000000000..ffb70c2a8 --- /dev/null +++ b/node_modules/pryjs/docs/js/katex_init.js @@ -0,0 +1,22 @@ +var elements = document.getElementsByTagName('script') + +Array.prototype.forEach.call(elements, function(element) { + if (element.type.indexOf('math/tex') != -1) { + // Extract math markdown + var textToRender = element.innerText || element.textContent; + + // Create span for KaTeX + var katexElement = document.createElement('span'); + + // Support inline and display math + if (element.type.indexOf('mode=display') != -1){ + katexElement.className += "math-display"; + textToRender = '\\displaystyle {' + textToRender + '}'; + } else { + katexElement.className += "math-inline"; + } + + katex.render(textToRender, katexElement); + element.parentNode.insertBefore(katexElement, element); + } +}); diff --git a/node_modules/pryjs/examples/fizzbuzz.coffee b/node_modules/pryjs/examples/fizzbuzz.coffee new file mode 100644 index 000000000..a976c5cde --- /dev/null +++ b/node_modules/pryjs/examples/fizzbuzz.coffee @@ -0,0 +1,18 @@ +pry = require('pryjs') + +# http://rosettacode.org/wiki/FizzBuzz#CoffeeScript +class FizzBuzz + + run: -> + for i in [1..100] + output = '' + eval(pry.it) + output += "Fizz" if i % 3 is 0 + output += "Buzz" if i % 5 is 0 + console.log output || i + + bar: -> + 10 + +fizz = new FizzBuzz() +fizz.run() diff --git a/node_modules/pryjs/examples/fizzbuzz.js b/node_modules/pryjs/examples/fizzbuzz.js new file mode 100644 index 000000000..a388a0cb9 --- /dev/null +++ b/node_modules/pryjs/examples/fizzbuzz.js @@ -0,0 +1,21 @@ +pry = require('pryjs'); + +// http://rosettacode.org/wiki/FizzBuzz#JavaScript +function FizzBuzz() { + this.run = function run () { + var i, output; + for (i = 1; i < 101; i++) { + output = ''; + eval(pry.it); + if (!(i % 3)) output += 'Fizz'; + if (!(i % 5)) output += 'Buzz'; + console.log(output || i); + } + }; + + this.bar = function bar () { + return 10 + } +}; + +new FizzBuzz().run() diff --git a/node_modules/pryjs/examples/package.json b/node_modules/pryjs/examples/package.json new file mode 100644 index 000000000..f8a3c0ca8 --- /dev/null +++ b/node_modules/pryjs/examples/package.json @@ -0,0 +1,10 @@ +{ + "name": "pry-examples", + "version": "1.0.0", + "description": "Pry usage examples", + "author": "Blaine Schmeisser", + "license": "MIT", + "dependencies": { + "pryjs": "file:../" + } +} diff --git a/node_modules/pryjs/features/continue.feature b/node_modules/pryjs/features/continue.feature new file mode 100644 index 000000000..1c0ebb095 --- /dev/null +++ b/node_modules/pryjs/features/continue.feature @@ -0,0 +1,16 @@ +Feature: Continue + As a user of pry.js + I want to continue the execution of the code + So I can see the side effects of my interactions + + Scenario: Skipping the iteration goes to the next variable + Given I have open the "fizzbuzz" example + When I type in "continue" + And I type in "i" + Then The output should match "2" + + Scenario: Works with the old stop command + Given I have open the "fizzbuzz" example + When I type in "stop" + And I type in "i" + Then The output should match "2" diff --git a/node_modules/pryjs/features/help.feature b/node_modules/pryjs/features/help.feature new file mode 100644 index 000000000..d11069123 --- /dev/null +++ b/node_modules/pryjs/features/help.feature @@ -0,0 +1,23 @@ +Feature: Help + As a user of pry.js + I want to be ask for help + So I can better use the tools provided + + Scenario: Getting all the help + Given I have open the "fizzbuzz" example + When I type in "help" + Then The output should match "whereami" + And The output should match "help" + + Scenario: Getting all the help with extra space + Given I have open the "fizzbuzz" example + When I type in "help " + Then The output should match "whereami" + And The output should match "help" + + Scenario: Getting specific help + Given I have open the "fizzbuzz" example + When I type in "help help" + Then The output should not match "whereami" + And The output should match "help" + And The output should be "2" lines diff --git a/node_modules/pryjs/features/play.feature b/node_modules/pryjs/features/play.feature new file mode 100644 index 000000000..e726e1932 --- /dev/null +++ b/node_modules/pryjs/features/play.feature @@ -0,0 +1,18 @@ +Feature: Play + As a user of pry.js + I want to play existing lines of code in context + So I can see the side effects of my interactions + + Scenario: Play a single line + Given I have open the "fizzbuzz" example + When I type in "i = 15" + When I type in "play 10" + And I type in "output" + Then The output should match "Fizz" + + Scenario: Play multiple lines + Given I have open the "fizzbuzz" example + When I type in "i = 15" + And I type in "play 10 11" + And I type in "output" + Then The output should match "FizzBuzz" diff --git a/node_modules/pryjs/features/step_definitions/myStepDefinitions.coffee b/node_modules/pryjs/features/step_definitions/myStepDefinitions.coffee new file mode 100644 index 000000000..05ac380c0 --- /dev/null +++ b/node_modules/pryjs/features/step_definitions/myStepDefinitions.coffee @@ -0,0 +1,42 @@ +myStepDefinitionsWrapper = -> + @World = require("../support/world").World + + @Given /^I have open the "([^"]*)" example$/, (example, callback) -> + @runCommand "node examples/#{example}.js", callback + + @When /^I type in "([^"]*)"$/, (command, callback) -> + @type command, callback + + @When /^I type in ctrl\+v$/, (callback) -> + @print_buffer new Buffer(String.fromCharCode(22)), callback + + @Then /^The output should match "([^"]*)"$/, (pattern, callback) -> + @getOutput (result) -> + if result.match(pattern) + callback() + else + callback.fail new Error("Expected to find #{pattern} in #{result}.") + + @Then /^The output should not match "([^"]*)"$/, (pattern, callback) -> + @getOutput (result) -> + if result.match(pattern) + callback.fail new Error("Expected not to find #{pattern} in #{result}.") + else + callback() + + @Then /^The output should be "([^"]*)"$/, (pattern, callback) -> + @getOutput (result) -> + if result == pattern + callback() + else + callback.fail new Error("Expected to find #{pattern} in #{result}.") + + @Then /^The output should be "([0-9]*)" lines?$/, (lines, callback) -> + @getOutput (result) -> + real_lines = result.trim().split('\n').length + if real_lines == parseInt(lines, 10) + callback() + else + callback.fail new Error("Expected #{lines} lines. Got #{real_lines}") + +module.exports = myStepDefinitionsWrapper diff --git a/node_modules/pryjs/features/support/after_hooks.coffee b/node_modules/pryjs/features/support/after_hooks.coffee new file mode 100644 index 000000000..b87508898 --- /dev/null +++ b/node_modules/pryjs/features/support/after_hooks.coffee @@ -0,0 +1,4 @@ +module.exports = -> + @After (callback) -> + @process.kill('SIGHUP'); + callback() diff --git a/node_modules/pryjs/features/support/world.coffee b/node_modules/pryjs/features/support/world.coffee new file mode 100644 index 000000000..f587a3c14 --- /dev/null +++ b/node_modules/pryjs/features/support/world.coffee @@ -0,0 +1,56 @@ +spawn = require('child_process').spawn +_ = require('underscore') +chalk = require('chalk') + +WorldConstructor = (callback) -> + + class World + + process: null + + output: [] + + runCommand: (command, callback) => + command = command.split(' ') + @waitForOutput(callback) + @process = spawn( + command[0], + command.slice(1), + cwd: "#{__dirname}/../../" + ) + @process.stdout.on 'data', (output) => + @output.push output.toString() + + type: (input, callback) => + @waitForOutput(callback) + @process.stdin.write "#{input}\n" + + print_buffer: (buffer, callback) => + @waitForOutput(callback) + @process.stdin.write buffer + + waitForOutput: (callback) => + @_waitForOutput(@output.length, new Date(), callback) + + # Subtract 2 + # 1 for index to count + # 1 account for the new prompt it sends + getOutput: (callback) => + output = _.compact(_.map(chalk.stripColor(@output.join('\n')) + .replace(/\u001b\[(?:\d|NaN)(?:G|J)/g, '') + .split('\n') + .join('\n') + .split(/(?:-{9}>|\.{10}|\[\d+\] pryjs>).*$/gm), (el) -> el.trim())) + callback(output[output.length - 1].trim()) + + _waitForOutput: (oldOutputLength, oldDate, callback) => + if new Date() - 4500 > oldDate + callback.fail new Error('Timeout of 4.5 seconds exceeded') + else if @output.length > oldOutputLength + callback() + else + setTimeout(@_waitForOutput.bind(@, oldOutputLength, oldDate, callback), 500) + + callback(new World) + +exports.World = WorldConstructor diff --git a/node_modules/pryjs/features/underscore.feature b/node_modules/pryjs/features/underscore.feature new file mode 100644 index 000000000..9c409d496 --- /dev/null +++ b/node_modules/pryjs/features/underscore.feature @@ -0,0 +1,10 @@ +Feature: Underscore + As a user of pry.js + I want to be able to use the last result + So I can better use the tools provided + + Scenario: Using dynamic underscore variable + Given I have open the "fizzbuzz" example + When I type in "42" + When I type in "_" + Then The output should match "42" diff --git a/node_modules/pryjs/features/version.feature b/node_modules/pryjs/features/version.feature new file mode 100644 index 000000000..b09663fd3 --- /dev/null +++ b/node_modules/pryjs/features/version.feature @@ -0,0 +1,9 @@ +Feature: Version + As a user of pry.js + I want to be able to use the Version command + So that I can see what version of pry.js I am using + + Scenario: I want to see the current pry.js version + Given I have open the "fizzbuzz" example + When I type in "version" + Then The output should match "\d+\.\d+\.\d+" diff --git a/node_modules/pryjs/features/whereami.feature b/node_modules/pryjs/features/whereami.feature new file mode 100644 index 000000000..59d123344 --- /dev/null +++ b/node_modules/pryjs/features/whereami.feature @@ -0,0 +1,19 @@ +Feature: Whereami + As a user of pry.js + I want to be able to use the Whereami command + So that I can see exactly where I am + + Scenario: The pointer should be on the pry statement + Given I have open the "fizzbuzz" example + When I type in "whereami" + Then The output should match "=>.*pry.it" + + Scenario: Should get 2 lines before and 1 after + Given I have open the "fizzbuzz" example + When I type in "whereami 2 1" + Then The output should be "4" lines + + Scenario: Should get 2 lines before and after + Given I have open the "fizzbuzz" example + When I type in "whereami 2 2" + Then The output should be "5" lines diff --git a/node_modules/pryjs/features/wtf.feature b/node_modules/pryjs/features/wtf.feature new file mode 100644 index 000000000..b34438a7a --- /dev/null +++ b/node_modules/pryjs/features/wtf.feature @@ -0,0 +1,15 @@ +Feature: Wtf + As a user of pry.js + I want to be able to use the Wtf command + So that I can see the last thrown exception + + Scenario: No caught exceptions + Given I have open the "fizzbuzz" example + When I type in "wtf" + Then The output should match "No errors" + + Scenario: No caught exceptions + Given I have open the "fizzbuzz" example + When I type in "throw new Error('Foobar!');" + And I type in "wtf" + Then The output should match "Foobar!" diff --git a/node_modules/pryjs/features/xecute.feature b/node_modules/pryjs/features/xecute.feature new file mode 100644 index 000000000..511c0990d --- /dev/null +++ b/node_modules/pryjs/features/xecute.feature @@ -0,0 +1,62 @@ +Feature: Execute + As a user of pry.js + I want to be able to execute javascript in scope + So I have a better idea of what my problem is + + Scenario: Looking at a variable + Given I have open the "fizzbuzz" example + When I type in "i" + Then The output should match "1" + + Scenario: Have the same scope + Given I have open the "fizzbuzz" example + When I type in "this.bar()" + Then The output should match "10" + + Scenario: Setting the variable + Given I have open the "fizzbuzz" example + When I type in "i = 20" + And I type in "i" + Then The output should match "20" + + Scenario: Executes javascript + Given I have open the "fizzbuzz" example + When I type in "if (true) { 'js'; }" + Then The output should be "js" + + Scenario: Executes coffeescript + Given I have open the "fizzbuzz" example + When I type in "mode" + And I type in "if true then 'coffee'" + Then The output should be "coffee" + + Scenario: Executes multiline javascript + Given I have open the "fizzbuzz" example + When I type in ctrl+v + And I type in "if (true) {" + And I type in "'hello world';" + And I type in "}" + And I type in "" + Then The output should be "hello world" + + Scenario: Executes multiline coffeescript + Given I have open the "fizzbuzz" example + When I type in "mode" + And I type in ctrl+v + And I type in "{" + And I type in "foo: 'hello world'" + And I type in "bar: 'baz'" + And I type in "}.foo" + And I type in "" + Then The output should be "hello world" + + Scenario: Should not overwrite global variables in Coffee + Given I have open the "fizzbuzz" example + When I type in "mode" + And I type in "i = i || 20" + Then The output should match "1" + + Scenario: Getting an error + Given I have open the "fizzbuzz" example + When I type in "i_do_not_exist" + Then The output should match "is not defined" diff --git a/node_modules/pryjs/lib/.gitkeep b/node_modules/pryjs/lib/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/node_modules/pryjs/package.json b/node_modules/pryjs/package.json new file mode 100644 index 000000000..554b0e81d --- /dev/null +++ b/node_modules/pryjs/package.json @@ -0,0 +1,76 @@ +{ + "_from": "pryjs", + "_id": "pryjs@1.0.3", + "_inBundle": false, + "_integrity": "sha1-msqACY7l3edrenu2047CrHIJR80=", + "_location": "/pryjs", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "pryjs", + "name": "pryjs", + "escapedName": "pryjs", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/pryjs/-/pryjs-1.0.3.tgz", + "_shasum": "9aca80098ee5dde76b7a7bb6d38ec2ac720947cd", + "_spec": "pryjs", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge", + "author": { + "name": "blainesch" + }, + "bin": { + "pryjs": "./bin/pryjs" + }, + "bugs": { + "url": "https://github.com/blainesch/pry.js/issues" + }, + "bundleDependencies": false, + "dependencies": { + "chalk": "^0.5.1", + "coffee-script": "^1.8.0", + "deasync": "~0.1.2", + "pygmentize-bundled": "^2.3.0", + "underscore": "^1.7.0" + }, + "deprecated": false, + "description": "Pry like ability in javascript.", + "devDependencies": { + "chai": "^1.10.0", + "cucumber": "^0.4.7", + "gh-pages": "^0.11.0", + "grunt": "^0.4.5", + "grunt-cli": "^1.2.0", + "grunt-contrib-clean": "^0.6.0", + "grunt-contrib-coffee": "^0.12.0", + "mocha": "^2.3.3", + "mocha-pride": "0.0.2", + "sinon": "^1.12.1" + }, + "directories": { + "example": "examples", + "test": "test" + }, + "homepage": "https://github.com/blainesch/pry.js", + "license": "MIT", + "main": "build/pry.js", + "name": "pryjs", + "repository": { + "type": "git", + "url": "git+https://github.com/blainesch/pry.js.git" + }, + "scripts": { + "build": "grunt", + "docs:publish": "gh-pages -d docs", + "pretest": "npm run build && cd examples && npm install", + "test": "mocha --recursive --reporter=mocha-pride --compilers coffee:coffee-script/register ./tests && cucumber.js" + }, + "version": "1.0.3" +} diff --git a/node_modules/pryjs/readme.md b/node_modules/pryjs/readme.md new file mode 100644 index 000000000..596a747a6 --- /dev/null +++ b/node_modules/pryjs/readme.md @@ -0,0 +1,50 @@ +## Pryjs + +A interactive repl for node, inspired by [pry](https://github.com/pry/pry). + +[![Build Status](https://travis-ci.org/blainesch/pry.js.svg?branch=master)](https://travis-ci.org/blainesch/pry.js) + +### Installing + +~~~ +npm install --save pryjs +~~~ + +### Usage + +Throw this beautiful snippet in the middle of your code: + +~~~ javascript +import pry from 'pryjs' +eval(pry.it) +~~~ + +~~~ javascript +pry = require('pryjs') +eval(pry.it) +~~~ + +You *MUST* name the variable `pry`. You are executing an anonymous function, and +this assumes the variable is named `pry` in your scope. This is so it can keep +prompting you. + +### Extra Commands + +While you are in the prompt there are a few things you might want to do: + +* `help` display all the available commands. +* `kill` completely stop the script. +* `mode` switch between javascript and coffeescript mode. Defaults to javascript. +* `play` play lines of code as if you had entered them. Accepts two integers: start and end. End defaults to start. +* `stop` will exit the pryjs prompt and continue through the app. +* `version` display the current version. +* `whereami` will show you exactly where you are in the code. Accepts two integers to replace the default 5 before and 5 after. +* `wtf` display the last caught exception. + +### Examples + +Examples can be found in the [examples directory](./examples). + +### Screenshots + +![pryjs](./assets/demo.png) diff --git a/node_modules/pryjs/src/pry.coffee b/node_modules/pryjs/src/pry.coffee new file mode 100644 index 000000000..79abbc90b --- /dev/null +++ b/node_modules/pryjs/src/pry.coffee @@ -0,0 +1,19 @@ +App = require('./pry/app') + +class Pry + + constructor: -> + @it = "(#{@_pry.toString()}).call(this)" + + _pry: -> + pry = require('pryjs') + _ = null + pry.open ((input) -> + _ = eval(input) + ).bind(@) + + open: (scope) -> + app = new App(scope) + app.open() + +module.exports = new Pry diff --git a/node_modules/pryjs/src/pry/app.coffee b/node_modules/pryjs/src/pry/app.coffee new file mode 100644 index 000000000..0565067d8 --- /dev/null +++ b/node_modules/pryjs/src/pry/app.coffee @@ -0,0 +1,41 @@ +SyncPrompt = require('./sync_prompt') +Output = require('./output/local_output') +commands = require('./commands') + +class App + + _commands: [] + + constructor: (@scope) -> + @output = new Output() + @prompt = new SyncPrompt({ + typeahead: @typeahead + }) + @prompt.on('data', @find_command) + + commands: -> + if @_commands.length is 0 + @_commands.push new command({@output, @scope}) for i,command of commands + @_commands + + typeahead: (input = '') => + items = [] + for command in @commands() + items = items.concat(command.typeahead(input)) + if input + items = items.filter (item) -> + item.indexOf(input) is 0 + [items, input] + + find_command: (input, chain) => + for command in @commands() + if match = command.match(input.trim()) + args = String(match[1]).trim().split(' ') + return command.execute.call command, args, chain + false + + open: -> + @prompt.type('whereami') + @prompt.open() + +module.exports = App diff --git a/node_modules/pryjs/src/pry/command.coffee b/node_modules/pryjs/src/pry/command.coffee new file mode 100644 index 000000000..f525825f9 --- /dev/null +++ b/node_modules/pryjs/src/pry/command.coffee @@ -0,0 +1,61 @@ +File = require('./file') +Range = require('./range') + +class Command + + # List of all initialized commands + @commands = {} + + # The name of your command + name: '' + + # Aliases of the command + aliases: [] + + # Standard definition of your command + definition: '' + + # Additional help information and usage. + help: '' + + # How many arguments you want. Number or range. + args: new Range(0, 0) + + constructor: ({@scope, @output}) -> + @stack = new Error().stack + @constructor.commands[@constructor.name] = @ + + command: (input) -> + for name, command of @commands() + return command if command.constructor.name.match(new RegExp(input, 'i')) + + commands: -> + @constructor.commands + + typeahead: -> + items = @aliases.slice(0) + items.push(@name) + items + + # Generates a regex based on the info given + command_regex: -> + subject = "^(?:#{@name}" + if @aliases.length > 0 + subject += "|#{@aliases.join('|')}" + subject += ")((?: (?:[^ ]+))#{@args.to_regex()})$" + new RegExp(subject) + + match: (input) -> + input.match(@command_regex()) + + find_file: -> + foundCall = false + for item in @stack.split('\n') + if foundCall + [_, file, line] = item.match(/([^ (:]+):(\d+):\d+/) + return new File(file, line) if file isnt '' + else if item.match /Pry\.open/ + foundCall = true + new File(__filename, 1) + +module.exports = Command diff --git a/node_modules/pryjs/src/pry/commands/continue.coffee b/node_modules/pryjs/src/pry/commands/continue.coffee new file mode 100644 index 000000000..b7891b1de --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/continue.coffee @@ -0,0 +1,12 @@ +Command = require('../command') + +class Continue extends Command + + name: 'continue' + aliases: ['exit', 'quit', 'stop'] + definition: 'Ends the current prompt and continues running the rest of the code.' + + execute: (args, chain) -> + chain.stop() + +module.exports = Continue diff --git a/node_modules/pryjs/src/pry/commands/help.coffee b/node_modules/pryjs/src/pry/commands/help.coffee new file mode 100644 index 000000000..a0522ff0a --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/help.coffee @@ -0,0 +1,34 @@ +Command = require('../command') +Range = require('../range') +chalk = require('chalk') + +class Help extends Command + + name: 'help' + aliases: ['\\?'] + definition: 'Shows a list of commands. Type `help foo` for help on the `foo` command.' + help: 'You just lost the game.' + args: new Range(0, 1) + + typeahead: (input = '') -> + if input.indexOf('help') is 0 + items = [] + for name,command of @commands() + items.push "help #{command.name}" if command.name + items + else + ['help'] + + execute: ([name], chain) -> + if name + command = @command(name) + @output.add(chalk.blue(command.name), '-', command.definition) + @output.add(command.help) + @output.sendAll() + else + for name, command of @commands() + @output.add(chalk.blue(command.name), '-', command.definition) if command.name + @output.sendAll() + chain.next() + +module.exports = Help diff --git a/node_modules/pryjs/src/pry/commands/index.coffee b/node_modules/pryjs/src/pry/commands/index.coffee new file mode 100644 index 000000000..f2f591675 --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/index.coffee @@ -0,0 +1,7 @@ +fs = require 'fs' + +for file in fs.readdirSync(__dirname) + if file.match(/\.(coffee|js)$/) && !file.match(/index\.(js|coffee)/) + file = file.substr 0, file.indexOf('.') + name = file.substring(0, 1).toUpperCase() + file.substring(1) + exports[name] = require("./#{file}") diff --git a/node_modules/pryjs/src/pry/commands/kill.coffee b/node_modules/pryjs/src/pry/commands/kill.coffee new file mode 100644 index 000000000..9d7278f54 --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/kill.coffee @@ -0,0 +1,14 @@ +Command = require('../command') + +class Kill extends Command + + name: 'kill!' + aliases: ['kill', 'exit!', 'quit!', 'stop!'] + definition: 'Exits from the entire script.' + + execute: (args, chain) -> + chain.stop() + process.kill() + false + +module.exports = Kill diff --git a/node_modules/pryjs/src/pry/commands/play.coffee b/node_modules/pryjs/src/pry/commands/play.coffee new file mode 100644 index 000000000..f11334dd8 --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/play.coffee @@ -0,0 +1,20 @@ +Command = require('../command') +Range = require('../range') + +class Play extends Command + + name: 'play' + definition: 'Play a specific line, or set of lines in the file you are in.' + help: '`play 1 2` will play lines 1 and 2.\n`play 1` will just play line 1.' + args: new Range(1, 2) + + constructor: -> + super + @file = @find_file() + + execute: ([start, end], chain) -> + end ||= start + @command('xecute').execute_code(@file.by_lines(start, end), @file.type()) + chain.next() + +module.exports = Play diff --git a/node_modules/pryjs/src/pry/commands/version.coffee b/node_modules/pryjs/src/pry/commands/version.coffee new file mode 100644 index 000000000..0a4b92300 --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/version.coffee @@ -0,0 +1,13 @@ +Command = require('../command') + +class Version extends Command + + name: 'version' + definition: 'Shows the current version or pry.js you are using.' + + execute: (args, chain) -> + content = require('fs').readFileSync("#{__dirname}/../../../package.json") + @output.send(JSON.parse(content)['version']) + chain.next() + +module.exports = Version diff --git a/node_modules/pryjs/src/pry/commands/whereami.coffee b/node_modules/pryjs/src/pry/commands/whereami.coffee new file mode 100644 index 000000000..7d0fdd764 --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/whereami.coffee @@ -0,0 +1,25 @@ +Command = require('../command') +Range = require('../range') + +class Whereami extends Command + + name: 'whereami' + definition: 'Shows you exactly where you are in the code.' + help: '`whereami` - Shows you where you are. +\n`whereami 6` - Gives you 6 lines before instead of 5. +\n`whereami 6 8` - Gives you 6 lines before instead of 5, and 8 lines after.' + args: new Range(0, 2) + + constructor: -> + super + @file = @find_file() + + execute: ([before, after], chain) -> + before ||= 5 + after ||= 5 + start = @file.line - parseInt(before, 10) + end = @file.line + parseInt(after, 10) + @output.send(@file.formatted_content_by_line(start, end)) + chain.next() + +module.exports = Whereami diff --git a/node_modules/pryjs/src/pry/commands/wtf.coffee b/node_modules/pryjs/src/pry/commands/wtf.coffee new file mode 100644 index 000000000..59a2c99f3 --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/wtf.coffee @@ -0,0 +1,16 @@ +Command = require('../command') + +class Wtf extends Command + + name: 'wtf' + definition: 'Shows the last caught exception.' + help: '`wtf` will show you the last caught exception.' + + execute: (args, chain) -> + if @command('xecute').last_error + @output.send(@command('xecute').last_error.stack) + else + @output.send('No errors') + chain.next() + +module.exports = Wtf diff --git a/node_modules/pryjs/src/pry/commands/xecute.coffee b/node_modules/pryjs/src/pry/commands/xecute.coffee new file mode 100644 index 000000000..79f51c331 --- /dev/null +++ b/node_modules/pryjs/src/pry/commands/xecute.coffee @@ -0,0 +1,40 @@ +Command = require('../command') +Range = require('../range') +Compiler = require('../compiler') + +class Xecute extends Command + + name: 'mode' + definition: 'Switched between CoffeeScript and JavaScript execution.' + help: 'Type `mode` to switch between using JavaScript or CoffeeScript.' + + last_error: null + + args: new Range(1, Infinity) + + constructor: -> + super + @compiler = new Compiler({@scope}) + + execute: (input, chain) -> + return @switch_mode(chain) if input[0] == 'mode' + @execute_code input.join(' ') + chain.next() + + execute_code: (code, language = null) -> + try + @output.send @compiler.execute(code, language) + catch err + @last_error = err + @output.send err + + switch_mode: (chain) -> + @compiler.toggle_mode() + @output.send "Switched mode to '#{@compiler.mode()}'." + chain.next() + + # Should always fallback to this + match: (input) -> + [input, input] + +module.exports = Xecute diff --git a/node_modules/pryjs/src/pry/compiler.coffee b/node_modules/pryjs/src/pry/compiler.coffee new file mode 100644 index 000000000..6c3b20f97 --- /dev/null +++ b/node_modules/pryjs/src/pry/compiler.coffee @@ -0,0 +1,31 @@ +coffee = require('coffee-script') +pry = require('../pry') + +class Compiler + + mode_id: 0 + + noVarPattern: /^\s*var .*$/gm + + modes: ['js', 'coffee'] + + constructor: ({@scope}) -> + + mode: -> + @modes[@mode_id] + + toggle_mode: -> + @mode_id = (@mode_id + 1) % @modes.length + + execute: (code, language = @modes[@mode_id]) -> + @["execute_#{language}"](code) + + execute_coffee: (code) -> + @execute_js(coffee + .compile(code, bare: true) + .replace(@noVarPattern, '')) + + execute_js: (code) -> + @scope(code) + +module.exports = Compiler diff --git a/node_modules/pryjs/src/pry/file.coffee b/node_modules/pryjs/src/pry/file.coffee new file mode 100644 index 000000000..92b1e1ac9 --- /dev/null +++ b/node_modules/pryjs/src/pry/file.coffee @@ -0,0 +1,28 @@ +fs = require('fs') +SyncHighlight = require('./sync_highlight') + +class File + + constructor: (@name, @line) -> + @line = parseInt(@line) + + type: -> + if @name.match /coffee$/ + 'coffee' + else + 'js' + + by_lines: (start, end = start) -> + @content().split('\n').slice(start - 1, end).join('\n') + + length: -> + @content().split('\n').length || 0 + + content: -> + @_content ||= fs.readFileSync(@name).toString() + + formatted_content_by_line: (start, end = start, line = @line) -> + start = (if start <= 0 then 1 else start) + new SyncHighlight(@content(), @type()).code_snippet(start, end, line) + +module.exports = File diff --git a/node_modules/pryjs/src/pry/output/local_output.coffee b/node_modules/pryjs/src/pry/output/local_output.coffee new file mode 100644 index 000000000..e8da5c3ae --- /dev/null +++ b/node_modules/pryjs/src/pry/output/local_output.coffee @@ -0,0 +1,16 @@ +class LocalOutput + + output: [] + + send: -> + console.log.apply(console.log, arguments) + + add: (args...) -> + @output.push args.join(' ') + + sendAll: -> + @send(@output.join('\n')) + @output = [] + + +module.exports = LocalOutput diff --git a/node_modules/pryjs/src/pry/range.coffee b/node_modules/pryjs/src/pry/range.coffee new file mode 100644 index 000000000..6ca362406 --- /dev/null +++ b/node_modules/pryjs/src/pry/range.coffee @@ -0,0 +1,18 @@ +class Range + + start: 0 + end: 0 + + constructor: (@start, @end) -> + throw "Start must be smaller than end" if @start > @end + + includes: (i) -> + @start <= i and i <= @end + + to_regex: -> + if @end == Infinity + "{#{@start},}" + else + "{#{@start},#{@end}}" + +module.exports = Range diff --git a/node_modules/pryjs/src/pry/sync_highlight.coffee b/node_modules/pryjs/src/pry/sync_highlight.coffee new file mode 100644 index 000000000..04bd18f93 --- /dev/null +++ b/node_modules/pryjs/src/pry/sync_highlight.coffee @@ -0,0 +1,55 @@ +pygmentize = require 'pygmentize-bundled' +deasync = require 'deasync' +chalk = require 'chalk' +util = require 'util' + +class SyncHighlight + + content: null + + type: null + + constructor: (obj, @type = 'javascript') -> + if typeof obj == 'function' + @content = obj.toString() + else if typeof obj == 'string' + @content = obj + else + @content = JSON.stringify(obj, @stringify, "\t") + + stringify: (key, value) -> + return util.inspect(value) if typeof value == 'function' + value + + highlight: -> + if chalk.supportsColor + done = data = false + pygmentize + lang: @type + format: "terminal" + , @content, (err, res) => + done = true + data = res.toString() + deasync.runLoopOnce() until done + else + data = @content + data + + code_snippet: (start, end, line_number, line_pointer = ' => ') -> + lines = @highlight().split('\n') + for line,key in lines + if key+1 == line_number + pointer = line_pointer + else + pointer = @_spaces(line_pointer.length) + lines[key] = "#{pointer}#{@_space(key+1)}#{chalk.cyan(key+1)}: #{line}" + lines.slice(start - 1, end).join('\n') + + # Assumes the biggest line number is 9999 + _space: (line) -> + @_spaces(4 - String(line).length) + + _spaces: (length, char = ' ') -> + new Array(length + 1).join(char) + +module.exports = SyncHighlight diff --git a/node_modules/pryjs/src/pry/sync_prompt.coffee b/node_modules/pryjs/src/pry/sync_prompt.coffee new file mode 100644 index 000000000..95b777dce --- /dev/null +++ b/node_modules/pryjs/src/pry/sync_prompt.coffee @@ -0,0 +1,96 @@ +readline = require('readline') +EventEmitter = require('events').EventEmitter +deasync = require('deasync') +_ = require('underscore') + +class MultilineState + + data: '' + + keypress: (input, chars) -> + @data += chars + if @data.match(/(\r|\n)\1$/) + @data = '' + input.state('single') + input.send_data() + else if chars.match(/(\r|\n)$/) + input.prompt() + + prompt: (input, prompt) -> + if @data == '' + input.cli.setPrompt(prompt.replace(/[^>](?!$)/g, '-')) + else + input.cli.setPrompt(prompt.replace(/.(?!$)/g, '.')) + input.cli.prompt() + +class SinglelineState + + keypress: (input, chars) -> + if chars is '\u0016' + input.state('multi') + input.prompt() + else if chars.match(/(\r|\n)$/) + input.send_data() + + prompt: (input, prompt) -> + input.cli.setPrompt(prompt) + input.cli.prompt() + +class SyncPrompt extends EventEmitter + + lines: '' + + count: 0 + + states: + multi: new MultilineState + single: new SinglelineState + + _state: 'single' + + done: false + + constructor: (@options = {}) -> + @options = _.extend(_.pick(process, 'stdin', 'stdout'), @options) + @cli = readline.createInterface + input: @options.stdin + output: @options.stdout + completer: @options.typeahead + @cli.on('line', @line) + @options.stdin.on('data', @keypress) + + state: (state) => + @_state = state if state + @states[@_state] + + line: (line) => + line = line.slice(1) if line.charCodeAt(0) is 22 + @lines += '\n' + line + + keypress: (chars) => + @state().keypress(@, chars.toString()) + + send_data: => + @count++ + @emit('data', @lines.trim(), next: @prompt, stop: @close) + @lines = '' + + prompt: => + @state().prompt(@, "[#{@count}] pryjs> ") + + open: -> + @done = false + @prompt() + deasync.runLoopOnce() until @done + + # Manually trigger input + type: (input) => + @lines = input + @send_data() + + close: => + @done = true + @options.stdin.removeListener('data', @keypress) + @cli.close() + +module.exports = SyncPrompt diff --git a/node_modules/pryjs/tests/app_spec.coffee b/node_modules/pryjs/tests/app_spec.coffee new file mode 100644 index 000000000..f0bb3c5d6 --- /dev/null +++ b/node_modules/pryjs/tests/app_spec.coffee @@ -0,0 +1,69 @@ +expect = require('chai').expect +sinon = require('sinon') +App = require('../src/pry/app') + +describe 'app', -> + + subject = null + + command = (ret_match, ret_execute) -> + match: sinon.stub().returns(ret_match) + execute: sinon.stub().returns(ret_execute) + + before (complete) -> + subject = new App + complete() + + describe '#find_command', -> + + describe 'given three commands', -> + + response = null + + before (complete) -> + subject._commands = [ + command(false, false) + command(true, true) + command(true, false) + ] + response = subject.find_command('foo') + complete() + + it 'returns true', -> + expect(response).to.equal true + + it 'calls the second command', -> + expect(subject.commands()[1].execute.calledOnce).to.equal true + + it 'doesnt call the first and third command', -> + expect(subject.commands()[0].execute.calledOnce).to.equal false + expect(subject.commands()[2].execute.calledOnce).to.equal false + + describe '#typeahead', -> + + describe 'given three commands', -> + + before (complete) -> + subject._commands = [ + typeahead: -> ['foo'] + , + typeahead: -> ['bar'] + , + typeahead: -> ['baz'] + ] + complete() + + describe 'given no input', -> + + it 'returns all items', -> + expect(subject.typeahead()[0]).to.deep.equal ['foo', 'bar', 'baz'] + + describe 'given input of "f"', -> + + it 'returns all items', -> + expect(subject.typeahead('f')[0]).to.deep.equal ['foo'] + + describe 'given input of "github"', -> + + it 'returns all items', -> + expect(subject.typeahead('github')[0]).to.deep.equal [] diff --git a/node_modules/pryjs/tests/command_spec.coffee b/node_modules/pryjs/tests/command_spec.coffee new file mode 100644 index 000000000..7657015cc --- /dev/null +++ b/node_modules/pryjs/tests/command_spec.coffee @@ -0,0 +1,107 @@ +expect = require('chai').expect +Command = require('../src/pry/command') +Range = require('../src/pry/range') + +describe 'Command', -> + + subject = null + + beforeEach (complete) -> + subject = new Command + scope: (p) -> p + output: + send: -> true + complete() + + describe '#command', -> + + beforeEach (complete) -> + subject.constructor.commands = + one: + constructor: + name: 'Blaine' + two: + constructor: + name: 'Sch' + complete() + + it 'matches case insensitive strings', -> + expect(subject.command('blaine').constructor.name).to.equal 'Blaine' + + describe '#typeahead', -> + + describe 'given a name and aliases', -> + + beforeEach (complete) -> + subject.name = 'foobar' + subject.aliases = ['fb', 'gh'] + complete() + + it 'matches case insensitive strings', -> + expect(subject.typeahead()).to.deep.equal ['fb', 'gh', 'foobar'] + + describe '#command_regex', -> + + describe 'given a name of foo and 1-3 arguments', -> + + beforeEach (complete) -> + subject.name = 'foo' + subject.args = new Range(0, 3) + complete() + + it 'matches foo', -> + expect('foo').to.match subject.command_regex() + + it 'matches foo bar', -> + expect('foo bar').to.match subject.command_regex() + + it 'matches foo bar baz guz', -> + expect('foo bar baz guz').to.match subject.command_regex() + + it 'doesnt matches foo bar baz guz gul', -> + expect('foo bar baz guz gul').to.not.match subject.command_regex() + + describe '#find_file', -> + + describe 'given a valid backtrace', -> + + beforeEach (complete) -> + subject.stack = 'ReferenceError: Position is not defined\n + at new Presenter (~/sites/devup/apps/pry.js/src/pry/presenter.coffee:14:16)\n + at Pry.open (~/sites/devup/apps/pry.js/src/pry.coffee:13:17)\n + at eval (:2:18)\n + at eval (:5:7)\n + at fizzBuzz (~/sites/devup/apps/pry.js/examples/fizzbuzz.coffee:6:5)\n + at Object. (~/sites/devup/apps/pry.js/examples/fizzbuzz.coffee:16:1)\n + at Object. (~/sites/devup/apps/pry.js/examples/fizzbuzz.coffee:1:1)\n + at Module._compile (module.js:456:26)\n + at Object.exports.run (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/coffee-script.js:119:23)\n + at compileScript (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/command.js:208:29)' + complete() + + it 'find the fizzBugg file', -> + expect(subject.find_file().name).to.eq '~/sites/devup/apps/pry.js/examples/fizzbuzz.coffee' + + it 'find the fizzBugg line', -> + expect(subject.find_file().line).to.eq 6 + + describe 'given a invalid backtrace', -> + + beforeEach (complete) -> + subject.stack = 'ReferenceError: Position is not defined\n + at new Presenter (~/sites/devup/apps/pry.js/src/pry/presenter.coffee:14:16)\n + at eval (:2:18)\n + at eval (:5:7)\n + at fizzBuzz (~/sites/devup/apps/pry.js/examples/fizzbuzz.coffee:6:5)\n + at Object. (~/sites/devup/apps/pry.js/examples/fizzbuzz.coffee:16:1)\n + at Object. (~/sites/devup/apps/pry.js/examples/fizzbuzz.coffee:1:1)\n + at Module._compile (module.js:456:26)\n + at Object.exports.run (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/coffee-script.js:119:23)\n + at compileScript (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/command.js:208:29)' + complete() + + it 'find the default command file', -> + expect(subject.find_file().name).to.match /command\.(coffee|js)$/ + + it 'finds the first line', -> + expect(subject.find_file().line).to.eq 1 diff --git a/node_modules/pryjs/tests/commands/help_spec.coffee b/node_modules/pryjs/tests/commands/help_spec.coffee new file mode 100644 index 000000000..38962f2ad --- /dev/null +++ b/node_modules/pryjs/tests/commands/help_spec.coffee @@ -0,0 +1,25 @@ +expect = require('chai').expect +sinon = require('sinon') +Help = require('../../src/pry/commands/help') + +describe 'Help', -> + + subject = null + spy = sinon.spy() + + before (complete) -> + subject = new Help + scope: (p) -> p + complete() + + describe '#typeahead', -> + + describe 'given I type nothing', -> + + it 'stops on the first index', -> + expect(subject.typeahead()).to.deep.equal ['help'] + + describe 'given I type "help"', -> + + it 'it gives me all the help commands', -> + expect(subject.typeahead('help')).to.deep.equal ['help help'] diff --git a/node_modules/pryjs/tests/commands/whereami_spec.coffee b/node_modules/pryjs/tests/commands/whereami_spec.coffee new file mode 100644 index 000000000..c52622c11 --- /dev/null +++ b/node_modules/pryjs/tests/commands/whereami_spec.coffee @@ -0,0 +1,38 @@ +expect = require('chai').expect +sinon = require('sinon') +Whereami = require('../../src/pry/commands/whereami') + +describe 'Whereami', -> + + subject = null + spy = sinon.spy() + + before (complete) -> + subject = new Whereami + scope: (p) -> p + output: + send: -> true + subject.file = + length: -> + 10 + formatted_content_by_line: spy + content: -> + 'The\nquick\nbrown\nfox\njumps\nover\nthe\nlazy\ndog' + complete() + + describe '#execute', -> + + describe 'given I am on line 3', -> + + before (complete) -> + subject.file.line = 3 + complete() + + describe 'given I call it with the default arguments', -> + + before (complete) -> + subject.execute([], next: sinon.spy()) + complete() + + it 'blindly puts lines numbers', -> + expect(spy.calledWith(-2, 8)).to.equal true diff --git a/node_modules/pryjs/tests/compiler_spec.coffee b/node_modules/pryjs/tests/compiler_spec.coffee new file mode 100644 index 000000000..11d5e3f46 --- /dev/null +++ b/node_modules/pryjs/tests/compiler_spec.coffee @@ -0,0 +1,46 @@ +expect = require('chai').expect +Compiler = require('../src/pry/compiler') + +describe 'Compiler', -> + + subject = null + + beforeEach (complete) -> + subject = new Compiler + scope: (input) -> + eval(input) + output: + send: -> + arguments + complete() + + describe '#toggle_mode', -> + + beforeEach (complete) -> + expect(subject.mode_id).to.equal 0 + subject.toggle_mode() + complete() + + it 'switches the mode to coffeescript', -> + expect(subject.mode_id).to.equal 1 + + it 'switches back to javascript', -> + subject.toggle_mode() + expect(subject.mode_id).to.equal 0 + + describe '#execute', -> + + describe 'in javascript mode', -> + + it 'can add numbers together', -> + expect(subject.execute('var i = 0;++i;')).to.equal 1 + + describe 'in coffee mode', -> + + beforeEach (complete) -> + subject.toggle_mode() + expect(subject.mode_id).to.equal 1 + complete() + + it 'can add numbers together', -> + expect(subject.execute('i = 0\n++i')).to.equal 1 diff --git a/node_modules/pryjs/tests/file_spec.coffee b/node_modules/pryjs/tests/file_spec.coffee new file mode 100644 index 000000000..5d4c26c12 --- /dev/null +++ b/node_modules/pryjs/tests/file_spec.coffee @@ -0,0 +1,46 @@ +expect = require('chai').expect +File = require('../src/pry/file') + +describe 'File', -> + + subject = null + + beforeEach (complete) -> + subject = new File('foo.coffee', 1) + subject.content = -> + 'The\nquick\nbrown\nfox\njumps\nover\nthe\nlazy\ndog' + complete() + + describe '#by_lines', -> + + it 'gives me the correct lines', -> + expect(subject.by_lines(1,2)).to.equal 'The\nquick' + + describe '#type', -> + + describe 'given a coffee file', -> + + beforeEach (complete) -> + subject.name = 'file.coffee' + complete() + + it 'returns coffee for a coffee file', -> + expect(subject.type()).to.equal 'coffee' + + describe 'given a js file', -> + + beforeEach (complete) -> + subject.name = 'file.js' + complete() + + it 'returns js', -> + expect(subject.type()).to.equal 'js' + + describe 'given a text file', -> + + beforeEach (complete) -> + subject.name = 'file.txt' + complete() + + it 'returns js', -> + expect(subject.type()).to.equal 'js' diff --git a/node_modules/pryjs/tests/range_spec.coffee b/node_modules/pryjs/tests/range_spec.coffee new file mode 100644 index 000000000..2f5961085 --- /dev/null +++ b/node_modules/pryjs/tests/range_spec.coffee @@ -0,0 +1,49 @@ +expect = require('chai').expect +Range = require('../src/pry/range') + +describe 'Range', -> + + subject = null + + describe '#includes', -> + + describe 'given a range of 1 to 100', -> + + beforeEach (complete) -> + subject = new Range(1, 100) + complete() + + it 'includes 1', -> + expect(subject.includes(1)).to.equal true + + it 'includes 100', -> + expect(subject.includes(100)).to.equal true + + it 'includes 50', -> + expect(subject.includes(50)).to.equal true + + it 'doesnt include 101', -> + expect(subject.includes(101)).to.equal false + + it 'doesnt include 0', -> + expect(subject.includes(0)).to.equal false + + describe '#to_regex', -> + + describe 'given a range of 1 to 100', -> + + beforeEach (complete) -> + subject = new Range(1, 100) + complete() + + it 'gives back the correct regex', -> + expect(subject.to_regex()).to.equal '{1,100}' + + describe 'given a range of 1 to Infinity', -> + + beforeEach (complete) -> + subject = new Range(1, Infinity) + complete() + + it 'gives back the correct regex', -> + expect(subject.to_regex()).to.equal '{1,}' diff --git a/node_modules/pryjs/tests/sync_highlight_spec.coffee b/node_modules/pryjs/tests/sync_highlight_spec.coffee new file mode 100644 index 000000000..67486b4fa --- /dev/null +++ b/node_modules/pryjs/tests/sync_highlight_spec.coffee @@ -0,0 +1,23 @@ +expect = require('chai').expect +chalk = require('chalk') +SyncHighlight = require('../src/pry/sync_highlight') + +describe 'SyncHighlight', -> + + subject = null + + beforeEach (complete) -> + subject = new SyncHighlight('foo.coffee', 'javascript') + subject.content = 'The\nquick\nbrown\nfox\njumps\nover\nthe\nlazy\ndog' + subject.highlight = -> + subject.content + complete() + + describe '#code_snippet', -> + + it 'contains a pointer on the correct line', -> + expect(subject.code_snippet(1, 9, 3).split('\n')[2]).to.match new RegExp('=>') + + it 'gives me the correct lines', -> + expect(subject.code_snippet(4, 5).split('\n')[0]).to.match /fox/ + expect(subject.code_snippet(4, 5).split('\n')[1]).to.match /jumps/ diff --git a/node_modules/pygmentize-bundled/.jshintrc b/node_modules/pygmentize-bundled/.jshintrc new file mode 100644 index 000000000..c8ef3ca40 --- /dev/null +++ b/node_modules/pygmentize-bundled/.jshintrc @@ -0,0 +1,59 @@ +{ + "predef": [ ] + , "bitwise": false + , "camelcase": false + , "curly": false + , "eqeqeq": false + , "forin": false + , "immed": false + , "latedef": false + , "noarg": true + , "noempty": true + , "nonew": true + , "plusplus": false + , "quotmark": true + , "regexp": false + , "undef": true + , "unused": true + , "strict": false + , "trailing": true + , "maxlen": 120 + , "asi": true + , "boss": true + , "debug": true + , "eqnull": true + , "esnext": true + , "evil": true + , "expr": true + , "funcscope": false + , "globalstrict": false + , "iterator": false + , "lastsemic": true + , "laxbreak": true + , "laxcomma": true + , "loopfunc": true + , "multistr": false + , "onecase": false + , "proto": false + , "regexdash": false + , "scripturl": true + , "smarttabs": false + , "shadow": false + , "sub": true + , "supernew": false + , "validthis": true + , "browser": true + , "couch": false + , "devel": false + , "dojo": false + , "mootools": false + , "node": true + , "nonstandard": true + , "prototypejs": false + , "rhino": false + , "worker": true + , "wsh": false + , "nomen": false + , "onevar": false + , "passfail": false +} \ No newline at end of file diff --git a/node_modules/pygmentize-bundled/.npmignore b/node_modules/pygmentize-bundled/.npmignore new file mode 100644 index 000000000..06954972e --- /dev/null +++ b/node_modules/pygmentize-bundled/.npmignore @@ -0,0 +1,8 @@ +*.tmp +.DS_Store +node_modules/ +*.pyc +.hg +.hgtags +.hgignore +vendor/pygments/tests/ \ No newline at end of file diff --git a/node_modules/pygmentize-bundled/LICENSE b/node_modules/pygmentize-bundled/LICENSE new file mode 100644 index 000000000..76d07a0cd --- /dev/null +++ b/node_modules/pygmentize-bundled/LICENSE @@ -0,0 +1,39 @@ +Copyright 2012, Rod Vagg (the "Original Author") +All rights reserved. + +MIT +no-false-attribs 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. + +Distributions of all or part of the Software intended to be used +by the recipients as they would use the unmodified Software, +containing modifications that substantially alter, remove, or +disable functionality of the Software, outside of the documented +configuration mechanisms provided by the Software, shall be +modified such that the Original Author's bug reporting email +addresses and urls are either replaced with the contact information +of the parties responsible for the changes, or removed entirely. + +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. + + +Except where noted, this license applies to any and all software +programs and associated documentation files created by the +Original Author, when distributed with the Software. \ No newline at end of file diff --git a/node_modules/pygmentize-bundled/README.md b/node_modules/pygmentize-bundled/README.md new file mode 100644 index 000000000..d2499c268 --- /dev/null +++ b/node_modules/pygmentize-bundled/README.md @@ -0,0 +1,96 @@ +# Pygmentize (Bundled) + +**Python's Pygments code formatter, for Node.js, distributed with Pygments** + +[![NPM](https://nodei.co/npm/pygmentize-bundled.png?downloads=true&stars=true&downloadRank=true)](https://nodei.co/npm/pygmentize-bundled/) [![NPM](https://nodei.co/npm-dl/pygmentize-bundled.png?months=6&height=3)](https://nodei.co/npm/pygmentize-bundled/) + +Can be used as either a *String-in, Buffer-out*, or as a Duplex stream. + +Compatible with both Python v2 and v3. + +**Note**: this library makes use of a child process which calls Python to invoke Pygments. This can cause performance problems where a large number of code blocks are being separately formatted. Consider using **[pygmentize-bundled-cached](https://github.com/rvagg/pygmentize-bundled-cached)**, an API-compatible wrapper for this library that keeps an on-disk cache of formatted code samples which will result in significantly faster formats when repeatedly formatting the same blocks of code. + +## API + +**pygmentize(options, code, callback)** + +Pygmentize a given `code` string and return it as a Buffer to the `callback` Function. + +* `options` contains options to be passed to Pygments (see [Options](#options)). +* `code` is a String to be formatted. +* `callback` is a Function, called when complete. The first argument will be an `error` object/string if there was a problem and the second argument will be a Buffer containing your formatted code. + +**pygmentize(options)** + +When you only supply the `options` argument, it will return a Duplex stream that you can pipe to and from to format your code. + +* `options` contains options to be passed to Pygments (see [Options](#options)). + +## Options + +Language/lexer, formatter, and their options are currently supported. Filters are not supported yet. + +* `lang`: source language/lexer name - `String` +* `format`: output formatter name - `String` +* `python`: the full path to the `python` command on the current system, defaults to `'python'` - `String` +* `options`: lexer and formatter options, each key/value pair is passed through to `pygmentize` with `-P` - `Object` + +## Examples + +The string interface is very simple: + +```js +var pygmentize = require('pygmentize-bundled') + +pygmentize({ lang: 'js', format: 'html' }, 'var a = "b";', function (err, result) { + console.log(result.toString()) +}) +``` + +Results in: + +```html +

+  var
+  a
+  =
+  "b"
+  ;
+
+``` + +Example with extra options: + +```js +var pygmentize = require('pygmentize-bundled') + +pygmentize({ lang: 'php', format: 'html', options: { startinline: 1 } }, 'var a = true;', function (err, result) { + console.log(result.toString()) +}) +``` + +A duplex streaming API is also available. Simply omit the `code` and `callback` arguments: + +```js +var pygmentize = require('pygmentize-bundled') + +process.stdin + .pipe(pygmentize({ lang: 'js', format: 'html' })) + .pipe(process.stdout); +``` + +Refer to the [Pygments documentation](http://pygments.org/docs/). For supported languages, see the list of [lexers](http://pygments.org/docs/lexers/), for supported formatted, see the list of [formatters](http://pygments.org/docs/formatters/). + +## Contributors + +* [Rod Vagg](https://github.com/rvagg) +* [Cyril Rohr](https://github.com/crohr) +* [Ahmed Fasih](https://github.com/fasiha) +* [Scott Walkinshaw](https://github.com/swalkinshaw) +* [Chris Wren](https://github.com/ChrisWren) + +## Licence & copyright + +Pygments (Bundled) is Copyright (c) 2012 Rod Vagg <@rvagg> and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. + +Pygments is licenced under the BSD licence. diff --git a/node_modules/pygmentize-bundled/index.js b/node_modules/pygmentize-bundled/index.js new file mode 100644 index 000000000..e27558e45 --- /dev/null +++ b/node_modules/pygmentize-bundled/index.js @@ -0,0 +1,144 @@ +const spawn = require('child_process').spawn + , exec = require('child_process').exec + , path = require('path') + , bl = require('bl') + , through2 = require('through2') + + , defaultFormat = 'html' + , defaultLang = 'js' + , defaultEncoding = 'utf8' + + +var pythonVersions = {} + + +function fromString (child, code, callback) { + var stdout = bl() + , stderr = bl() + , ec = 0 + , exitClose = function () { + if (++ec < 2) + return + + callback(null, stdout.slice()) + } + + child.stdout.pipe(stdout) + child.stderr.pipe(stderr) + + child.on('exit', function (code) { + if (code !== 0) { + ec = -1 + return callback(new Error('Error calling `pygmentize`: ' + stderr.toString())) + } + exitClose() + }) + child.on('close', exitClose) + + child.stdin.write(code) + child.stdin.end() +} + +function fromStream (retStream, intStream, child) { + var stderr = bl() + , outStream = through2(function (chunk, enc, callback) { + retStream.__write(chunk, enc, callback) + }) + + intStream.pipe(child.stdin) + child.stdout.pipe(outStream) + child.stderr.pipe(stderr) + + child.on('exit', function (code) { + if (code !== 0) + retStream.emit('error', stderr.toString()) + retStream.__end() + }) +} + + +function pygmentize (options, code, callback) { + options = options || {} + + var execArgs = [ + '-f', options.format || defaultFormat + , '-l', options.lang || defaultLang + , '-P', 'encoding=' + (options.encoding || defaultEncoding) + ] + , toString = typeof code == 'string' && typeof callback == 'function' + , retStream = !toString && through2() + , intStream = !toString && through2() + + if (typeof options.options == 'object') { + Object.keys(options.options).forEach(function (key) { + execArgs.push('-P', key + '=' + options.options[key]) + }) + } + + spawnPygmentize(options, execArgs, function (err, child) { + if (toString) { + if (err) + return callback(err) + return fromString(child, code, callback) + } + + // else stream + if (err) + return retStream.emit('error', err) + fromStream(retStream, intStream, child) + }) + + if (retStream) { + retStream.__write = retStream.write + retStream.write = intStream.write.bind(intStream) + retStream.__end = retStream.end + retStream.end = intStream.end.bind(intStream) + } + + return retStream +} + + +function spawnPygmentize (options, execArgs, callback) { + var python = typeof options.python == 'string' ? options.python : 'python' + + pythonVersion(python, function (err, version) { + if (err) + return callback(err) + if (version != 2 && version != 3) + return callback(new Error('Unsupported Python version: ' + version)) + + var pyg = path.join( + __dirname + , 'vendor/pygments' + , version == 2 ? 'build-2.7' : 'build-3.3' + , 'pygmentize' + ) + + callback(null, spawn(python, [ pyg ].concat(execArgs))) + }) +} + + +function pythonVersion (python, callback) { + if (pythonVersions[python]) + return callback(null, pythonVersions[python]) + + exec(python + ' -V', function (err, stdout, stderr) { + if (err) + return callback(err) + + var m = stderr.toString().match(/^Python (\d)[.\d]+/i) + if (!m) + m = stdout.toString().match(/^Python (\d)[.\d]+/i) + if (!m) + return callback(new Error('Cannot determine Python version: [' + stderr.toString() + ']')) + + pythonVersions[python] = +m[1] + + return callback(null, +m[1]) + }) +} + + +module.exports = pygmentize diff --git a/node_modules/pygmentize-bundled/package.json b/node_modules/pygmentize-bundled/package.json new file mode 100644 index 000000000..2861267f9 --- /dev/null +++ b/node_modules/pygmentize-bundled/package.json @@ -0,0 +1,65 @@ +{ + "_from": "pygmentize-bundled@^2.3.0", + "_id": "pygmentize-bundled@2.3.0", + "_inBundle": false, + "_integrity": "sha1-1CXe2o0TaXW5M+3jYxNfYjNQgUo=", + "_location": "/pygmentize-bundled", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "pygmentize-bundled@^2.3.0", + "name": "pygmentize-bundled", + "escapedName": "pygmentize-bundled", + "rawSpec": "^2.3.0", + "saveSpec": null, + "fetchSpec": "^2.3.0" + }, + "_requiredBy": [ + "/pryjs" + ], + "_resolved": "https://registry.npmjs.org/pygmentize-bundled/-/pygmentize-bundled-2.3.0.tgz", + "_shasum": "d425deda8d136975b933ede363135f623350814a", + "_spec": "pygmentize-bundled@^2.3.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/pryjs", + "authors": [ + "Rod Vagg @rvagg (https://github.com/rvagg)", + "Cyril Rohr @crohr (https://github.com/crohr)", + "Ahmed Fasih (https://github.com/fasiha)", + "Scott Walkinshaw (https://github.com/swalkinshaw)", + "Chris Wren (https://github.com/ChrisWren)" + ], + "bugs": { + "url": "https://github.com/rvagg/node-pygmentize-bundled/issues" + }, + "bundleDependencies": false, + "dependencies": { + "bl": "~0.4.1", + "through2": "~0.2.1" + }, + "deprecated": false, + "description": "A simple wrapper around Python's Pygments code formatter, with Pygments bundled", + "devDependencies": { + "stream-equal": "~0.1.5", + "tape": "~3.0.3" + }, + "homepage": "https://github.com/rvagg/node-pygmentize-bundled#readme", + "keywords": [ + "pygments", + "pygmentize", + "syntax", + "highlight", + "stream" + ], + "license": "MIT", + "main": "index.js", + "name": "pygmentize-bundled", + "repository": { + "type": "git", + "url": "git+https://github.com/rvagg/node-pygmentize-bundled.git" + }, + "scripts": { + "test": "node ./test.js" + }, + "version": "2.3.0" +} diff --git a/node_modules/pygmentize-bundled/test-fixtures/active_model.html b/node_modules/pygmentize-bundled/test-fixtures/active_model.html new file mode 100644 index 000000000..15f61d29a --- /dev/null +++ b/node_modules/pygmentize-bundled/test-fixtures/active_model.html @@ -0,0 +1,222 @@ +
require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/hash/except'
+require 'active_model/errors'
+require 'active_model/validations/callbacks'
+
+module ActiveModel
+
+  # == Active Model Validations
+  #
+  # Provides a full validation framework to your objects.
+  #
+  # A minimal implementation could be:
+  #
+  #   class Person
+  #     include ActiveModel::Validations
+  #
+  #     attr_accessor :first_name, :last_name
+  #
+  #     validates_each :first_name, :last_name do |record, attr, value|
+  #       record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
+  #     end
+  #   end
+  #
+  # Which provides you with the full standard validation stack that you
+  # know from Active Record:
+  #
+  #   person = Person.new
+  #   person.valid?                   # => true
+  #   person.invalid?                 # => false
+  #
+  #   person.first_name = 'zoolander'
+  #   person.valid?                   # => false
+  #   person.invalid?                 # => true
+  #   person.errors                   # => #<Hash {:first_name=>["starts with z."]}>
+  #
+  # Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+ method
+  # to your instances initialized with a new <tt>ActiveModel::Errors</tt> object, so
+  # there is no need for you to do this manually.
+  #
+  module Validations
+    extend ActiveSupport::Concern
+
+    included do
+      extend ActiveModel::Callbacks
+      extend ActiveModel::Translation
+
+      extend  HelperMethods
+      include HelperMethods
+
+      attr_accessor :validation_context
+      define_callbacks :validate, :scope => :name
+
+      extend ActiveModel::Configuration
+      config_attribute :_validators
+      self._validators = Hash.new { |h,k| h[k] = [] }
+    end
+
+    module ClassMethods
+      # Validates each attribute against a block.
+      #
+      #   class Person
+      #     include ActiveModel::Validations
+      #
+      #     attr_accessor :first_name, :last_name
+      #
+      #     validates_each :first_name, :last_name do |record, attr, value|
+      #       record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
+      #     end
+      #   end
+      #
+      # Options:
+      # * <tt>:on</tt> - Specifies the context where this validation is active
+      #   (e.g. <tt>:on => :create</tt> or <tt>:on => :custom_validation_context</tt>)
+      # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
+      # * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
+      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
+      #   if the validation should occur (e.g. <tt>:if => :allow_validation</tt>,
+      #   or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The method,
+      #   proc or string should return or evaluate to a true or false value.
+      # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
+      #   not occur (e.g. <tt>:unless => :skip_validation</tt>, or
+      #   <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
+      #   method, proc or string should return or evaluate to a true or false value.
+      def validates_each(*attr_names, &block)
+        options = attr_names.extract_options!.symbolize_keys
+        validates_with BlockValidator, options.merge(:attributes => attr_names.flatten), &block
+      end
+
+      # Adds a validation method or block to the class. This is useful when
+      # overriding the +validate+ instance method becomes too unwieldy and
+      # you're looking for more descriptive declaration of your validations.
+      #
+      # This can be done with a symbol pointing to a method:
+      #
+      #   class Comment
+      #     include ActiveModel::Validations
+      #
+      #     validate :must_be_friends
+      #
+      #     def must_be_friends
+      #       errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee)
+      #     end
+      #   end
+      #
+      # With a block which is passed with the current record to be validated:
+      #
+      #   class Comment
+      #     include ActiveModel::Validations
+      #
+      #     validate do |comment|
+      #       comment.must_be_friends
+      #     end
+      #
+      #     def must_be_friends
+      #       errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee)
+      #     end
+      #   end
+      #
+      # Or with a block where self points to the current record to be validated:
+      #
+      #   class Comment
+      #     include ActiveModel::Validations
+      #
+      #     validate do
+      #       errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee)
+      #     end
+      #   end
+      #
+      def validate(*args, &block)
+        options = args.extract_options!
+        if options.key?(:on)
+          options = options.dup
+          options[:if] = Array(options[:if])
+          options[:if].unshift("validation_context == :#{options[:on]}")
+        end
+        args << options
+        set_callback(:validate, *args, &block)
+      end
+
+      # List all validators that are being used to validate the model using
+      # +validates_with+ method.
+      def validators
+        _validators.values.flatten.uniq
+      end
+
+      # List all validators that being used to validate a specific attribute.
+      def validators_on(*attributes)
+        attributes.map do |attribute|
+          _validators[attribute.to_sym]
+        end.flatten
+      end
+
+      # Check if method is an attribute method or not.
+      def attribute_method?(attribute)
+        method_defined?(attribute)
+      end
+
+      # Copy validators on inheritance.
+      def inherited(base)
+        dup = _validators.dup
+        base._validators = dup.each { |k, v| dup[k] = v.dup }
+        super
+      end
+    end
+
+    # Returns the +Errors+ object that holds all information about attribute error messages.
+    def errors
+      @errors ||= Errors.new(self)
+    end
+
+    # Runs all the specified validations and returns true if no errors were added
+    # otherwise false. Context can optionally be supplied to define which callbacks
+    # to test against (the context is defined on the validations using :on).
+    def valid?(context = nil)
+      current_context, self.validation_context = validation_context, context
+      errors.clear
+      run_validations!
+    ensure
+      self.validation_context = current_context
+    end
+
+    # Performs the opposite of <tt>valid?</tt>. Returns true if errors were added,
+    # false otherwise.
+    def invalid?(context = nil)
+      !valid?(context)
+    end
+
+    # Hook method defining how an attribute value should be retrieved. By default
+    # this is assumed to be an instance named after the attribute. Override this
+    # method in subclasses should you need to retrieve the value for a given
+    # attribute differently:
+    #
+    #   class MyClass
+    #     include ActiveModel::Validations
+    #
+    #     def initialize(data = {})
+    #       @data = data
+    #     end
+    #
+    #     def read_attribute_for_validation(key)
+    #       @data[key]
+    #     end
+    #   end
+    #
+    alias :read_attribute_for_validation :send
+
+  protected
+
+    def run_validations!
+      run_callbacks :validate
+      errors.empty?
+    end
+  end
+end
+
+Dir[File.dirname(__FILE__) + "/validations/*.rb"].sort.each do |path|
+  filename = File.basename(path)
+  require "active_model/validations/#{filename}"
+end
+
diff --git a/node_modules/pygmentize-bundled/test-fixtures/active_model.rb b/node_modules/pygmentize-bundled/test-fixtures/active_model.rb new file mode 100644 index 000000000..0e15155b8 --- /dev/null +++ b/node_modules/pygmentize-bundled/test-fixtures/active_model.rb @@ -0,0 +1,221 @@ +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/hash/except' +require 'active_model/errors' +require 'active_model/validations/callbacks' + +module ActiveModel + + # == Active Model Validations + # + # Provides a full validation framework to your objects. + # + # A minimal implementation could be: + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :first_name, :last_name + # + # validates_each :first_name, :last_name do |record, attr, value| + # record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z + # end + # end + # + # Which provides you with the full standard validation stack that you + # know from Active Record: + # + # person = Person.new + # person.valid? # => true + # person.invalid? # => false + # + # person.first_name = 'zoolander' + # person.valid? # => false + # person.invalid? # => true + # person.errors # => #["starts with z."]}> + # + # Note that ActiveModel::Validations automatically adds an +errors+ method + # to your instances initialized with a new ActiveModel::Errors object, so + # there is no need for you to do this manually. + # + module Validations + extend ActiveSupport::Concern + + included do + extend ActiveModel::Callbacks + extend ActiveModel::Translation + + extend HelperMethods + include HelperMethods + + attr_accessor :validation_context + define_callbacks :validate, :scope => :name + + extend ActiveModel::Configuration + config_attribute :_validators + self._validators = Hash.new { |h,k| h[k] = [] } + end + + module ClassMethods + # Validates each attribute against a block. + # + # class Person + # include ActiveModel::Validations + # + # attr_accessor :first_name, :last_name + # + # validates_each :first_name, :last_name do |record, attr, value| + # record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z + # end + # end + # + # Options: + # * :on - Specifies the context where this validation is active + # (e.g. :on => :create or :on => :custom_validation_context) + # * :allow_nil - Skip validation if attribute is +nil+. + # * :allow_blank - Skip validation if attribute is blank. + # * :if - Specifies a method, proc or string to call to determine + # if the validation should occur (e.g. :if => :allow_validation, + # or :if => Proc.new { |user| user.signup_step > 2 }). The method, + # proc or string should return or evaluate to a true or false value. + # * :unless - Specifies a method, proc or string to call to determine if the validation should + # not occur (e.g. :unless => :skip_validation, or + # :unless => Proc.new { |user| user.signup_step <= 2 }). The + # method, proc or string should return or evaluate to a true or false value. + def validates_each(*attr_names, &block) + options = attr_names.extract_options!.symbolize_keys + validates_with BlockValidator, options.merge(:attributes => attr_names.flatten), &block + end + + # Adds a validation method or block to the class. This is useful when + # overriding the +validate+ instance method becomes too unwieldy and + # you're looking for more descriptive declaration of your validations. + # + # This can be done with a symbol pointing to a method: + # + # class Comment + # include ActiveModel::Validations + # + # validate :must_be_friends + # + # def must_be_friends + # errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee) + # end + # end + # + # With a block which is passed with the current record to be validated: + # + # class Comment + # include ActiveModel::Validations + # + # validate do |comment| + # comment.must_be_friends + # end + # + # def must_be_friends + # errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee) + # end + # end + # + # Or with a block where self points to the current record to be validated: + # + # class Comment + # include ActiveModel::Validations + # + # validate do + # errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee) + # end + # end + # + def validate(*args, &block) + options = args.extract_options! + if options.key?(:on) + options = options.dup + options[:if] = Array(options[:if]) + options[:if].unshift("validation_context == :#{options[:on]}") + end + args << options + set_callback(:validate, *args, &block) + end + + # List all validators that are being used to validate the model using + # +validates_with+ method. + def validators + _validators.values.flatten.uniq + end + + # List all validators that being used to validate a specific attribute. + def validators_on(*attributes) + attributes.map do |attribute| + _validators[attribute.to_sym] + end.flatten + end + + # Check if method is an attribute method or not. + def attribute_method?(attribute) + method_defined?(attribute) + end + + # Copy validators on inheritance. + def inherited(base) + dup = _validators.dup + base._validators = dup.each { |k, v| dup[k] = v.dup } + super + end + end + + # Returns the +Errors+ object that holds all information about attribute error messages. + def errors + @errors ||= Errors.new(self) + end + + # Runs all the specified validations and returns true if no errors were added + # otherwise false. Context can optionally be supplied to define which callbacks + # to test against (the context is defined on the validations using :on). + def valid?(context = nil) + current_context, self.validation_context = validation_context, context + errors.clear + run_validations! + ensure + self.validation_context = current_context + end + + # Performs the opposite of valid?. Returns true if errors were added, + # false otherwise. + def invalid?(context = nil) + !valid?(context) + end + + # Hook method defining how an attribute value should be retrieved. By default + # this is assumed to be an instance named after the attribute. Override this + # method in subclasses should you need to retrieve the value for a given + # attribute differently: + # + # class MyClass + # include ActiveModel::Validations + # + # def initialize(data = {}) + # @data = data + # end + # + # def read_attribute_for_validation(key) + # @data[key] + # end + # end + # + alias :read_attribute_for_validation :send + + protected + + def run_validations! + run_callbacks :validate + errors.empty? + end + end +end + +Dir[File.dirname(__FILE__) + "/validations/*.rb"].sort.each do |path| + filename = File.basename(path) + require "active_model/validations/#{filename}" +end diff --git a/node_modules/pygmentize-bundled/test.js b/node_modules/pygmentize-bundled/test.js new file mode 100644 index 000000000..ca808c5cf --- /dev/null +++ b/node_modules/pygmentize-bundled/test.js @@ -0,0 +1,104 @@ +const test = require('tape') + , pygments = require('./') + , fs = require('fs') + , path = require('path') + , streamEqual = require('stream-equal') + + +function createTests (test, pygments) { + function simpleStringConversionTest (python) { + return function (t) { + var cases = [ + { + lang: 'js' + , format: 'html' + , input: 'var a = "b";' + , output: '
var a '
+                    + '= "b";
' + } + , { + lang: 'c++' + , format: 'console' + , input: 'bool a = true;' + , output: '\u001b[36mbool\u001b[39;49;00m \u001b[39;49;00ma\u001b[39;49;00m ' + + '\u001b[39;49;00m=\u001b[39;49;00m \u001b[39;49;00m\u001b[36mtrue\u001b[39;49;00m;\u001b[39;49;00m' + } + , { + lang: 'php' + , format: 'html' + , input: 'var a = true;' + , output: '
var a = true;
' + } + , { + lang: 'php' + , format: 'html' + , options: { startinline: 1 } + , input: 'var a = true;' + , output: '
var a '
+                    + '= true;
' + } + ] + + t.plan(cases.length * 3) + + cases.forEach(function (c) { + pygments( + { + lang : c.lang + , format : c.format + , options : c.options || {} + , python : python + } + , c.input + , function (err, result) { + t.equal(err, null) + t.ok(Buffer.isBuffer(result), 'isBuffer') + result = result.toString().replace(/\n/g, '') + t.equal(result, c.output) + } + ) + }) + } + } + + function fileConversionTest (python) { + return function (t) { + t.plan(2) + + var fileIn = fs.createReadStream(__dirname + '/test-fixtures/active_model.rb') + , fileOut = fs.createWriteStream( + __dirname + '/test-fixtures/active_model.tmp' + , { flags: 'w+', encoding: null, mode: 0666 } + ) + + fileIn.pipe(pygments({ lang: 'rb', format: 'html', python: python })).pipe(fileOut) + + fileOut.on('close', function() { + var expectedResult = fs.createReadStream(path.join(__dirname, '/test-fixtures/active_model.html')) + , result = fs.createReadStream(path.join(__dirname, '/test-fixtures/active_model.tmp')) + + streamEqual(expectedResult, result, function (err, equal) { + t.notOk(err, 'no error') + t.ok(equal, 'stream equal') + }) + }) + } + } + + test('simple string conversions', simpleStringConversionTest()) + test('file conversions', fileConversionTest()) + + if (fs.existsSync('/usr/bin/python3')) { + test('simple string conversions (python3)', simpleStringConversionTest('/usr/bin/python3')) + test('file conversions (python3)', fileConversionTest('/usr/bin/python3')) + } else { + console.error('NO /usr/bin/python3, not testing Python3') + } +} + + +module.exports = createTests + + +if (require.main === module) + createTests(test, pygments) diff --git a/node_modules/pygmentize-bundled/vendor/pygments/AUTHORS b/node_modules/pygmentize-bundled/vendor/pygments/AUTHORS new file mode 100644 index 000000000..1bedef4b3 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/AUTHORS @@ -0,0 +1,172 @@ +Pygments is written and maintained by Georg Brandl . + +Major developers are Tim Hatch and Armin Ronacher +. + +Other contributors, listed alphabetically, are: + +* Sam Aaron -- Ioke lexer +* Ali Afshar -- image formatter +* Thomas Aglassinger -- Rexx lexer +* Kumar Appaiah -- Debian control lexer +* Andreas Amann -- AppleScript lexer +* Timothy Armstrong -- Dart lexer fixes +* Jeffrey Arnold -- R/S, Rd, BUGS, Jags, and Stan lexers +* Jeremy Ashkenas -- CoffeeScript lexer +* Stefan Matthias Aust -- Smalltalk lexer +* Ben Bangert -- Mako lexers +* Max Battcher -- Darcs patch lexer +* Thomas Baruchel -- APL lexer +* Tim Baumann -- (Literate) Agda lexer +* Paul Baumgart, 280 North, Inc. -- Objective-J lexer +* Michael Bayer -- Myghty lexers +* John Benediktsson -- Factor lexer +* Christopher Bertels -- Fancy lexer +* Jarrett Billingsley -- MiniD lexer +* Adam Blinkinsop -- Haskell, Redcode lexers +* Frits van Bommel -- assembler lexers +* Pierre Bourdon -- bugfixes +* Hiram Chirino -- Scaml and Jade lexers +* Ian Cooper -- VGL lexer +* David Corbett -- Inform and Jasmin lexers +* Leaf Corcoran -- MoonScript lexer +* Christopher Creutzig -- MuPAD lexer +* Daniël W. Crompton - Pike lexer +* Pete Curry -- bugfixes +* Bryan Davis -- EBNF lexer +* Owen Durni -- Haxe lexer +* Alexander Dutton, Oxford University Computing Services -- SPARQL lexer +* Nick Efford -- Python 3 lexer +* Sven Efftinge -- Xtend lexer +* Artem Egorkine -- terminal256 formatter +* James H. Fisher -- PostScript lexer +* William S. Fulton -- SWIG lexer +* Carlos Galdino -- Elixir and Elixir Console lexers +* Michael Galloy -- IDL lexer +* Naveen Garg -- Autohotkey lexer +* Laurent Gautier -- R/S lexer +* Alex Gaynor -- PyPy log lexer +* Richard Gerkin -- Igor Pro lexer +* Alain Gilbert -- TypeScript lexer +* Alex Gilding -- BlitzBasic lexer +* Bertrand Goetzmann -- Groovy lexer +* Krzysiek Goj -- Scala lexer +* Matt Good -- Genshi, Cheetah lexers +* Michał Górny -- vim modeline support +* Patrick Gotthardt -- PHP namespaces support +* Olivier Guibe -- Asymptote lexer +* Jordi Gutiérrez Hermoso -- Octave lexer +* Martin Harriman -- SNOBOL lexer +* Matthew Harrison -- SVG formatter +* Steven Hazel -- Tcl lexer +* Aslak Hellesøy -- Gherkin lexer +* Greg Hendershott -- Racket lexer +* David Hess, Fish Software, Inc. -- Objective-J lexer +* Varun Hiremath -- Debian control lexer +* Rob Hoelz -- Perl 6 lexer +* Doug Hogan -- Mscgen lexer +* Ben Hollis -- Mason lexer +* Max Horn -- GAP lexer +* Dustin Howett -- Logos lexer +* Alastair Houghton -- Lexer inheritance facility +* Tim Howard -- BlitzMax lexer +* Ivan Inozemtsev -- Fantom lexer +* Brian R. Jackson -- Tea lexer +* Christian Jann -- ShellSession lexer +* Dennis Kaarsemaker -- sources.list lexer +* Dmitri Kabak - Inferno Limbo lexer +* Igor Kalnitsky -- vhdl lexer +* Alexander Kit -- MaskJS lexer +* Pekka Klärck -- Robot Framework lexer +* Eric Knibbe -- Lasso lexer +* Stepan Koltsov -- Clay lexer +* Adam Koprowski -- Opa lexer +* Benjamin Kowarsch -- Modula-2 lexer +* Domen Kožar -- Nix lexer +* Alexander Kriegisch -- Kconfig and AspectJ lexers +* Marek Kubica -- Scheme lexer +* Jochen Kupperschmidt -- Markdown processor +* Gerd Kurzbach -- Modelica lexer +* Jon Larimer, Google Inc. -- Smali lexer +* Olov Lassus -- Dart lexer +* Sylvestre Ledru -- Scilab lexer +* Mark Lee -- Vala lexer +* Ben Mabey -- Gherkin lexer +* Angus MacArthur -- QML lexer +* Louis Marchand -- Eiffel lexer +* Simone Margaritelli -- Hybris lexer +* Kirk McDonald -- D lexer +* Gordon McGregor -- SystemVerilog lexer +* Stephen McKamey -- Duel/JBST lexer +* Brian McKenna -- F# lexer +* Charles McLaughlin -- Puppet lexer +* Lukas Meuser -- BBCode formatter, Lua lexer +* Cat Miller -- Pig lexer +* Paul Miller -- LiveScript lexer +* Hong Minhee -- HTTP lexer +* Michael Mior -- Awk lexer +* Bruce Mitchener -- Dylan lexer rewrite +* Reuben Morais -- SourcePawn lexer +* Jon Morton -- Rust lexer +* Paulo Moura -- Logtalk lexer +* Mher Movsisyan -- DTD lexer +* Ana Nelson -- Ragel, ANTLR, R console lexers +* Nam T. Nguyen -- Monokai style +* Jesper Noehr -- HTML formatter "anchorlinenos" +* Mike Nolta -- Julia lexer +* Jonas Obrist -- BBCode lexer +* Edward O'Callaghan -- Cryptol lexer +* David Oliva -- Rebol lexer +* Pat Pannuto -- nesC lexer +* Jon Parise -- Protocol buffers lexer +* Ronny Pfannschmidt -- BBCode lexer +* Benjamin Peterson -- Test suite refactoring +* Dominik Picheta -- Nimrod lexer +* Andrew Pinkham -- RTF Formatter Refactoring +* Clément Prévost -- UrbiScript lexer +* raichoo -- Idris lexer +* Kashif Rasul -- CUDA lexer +* Justin Reidy -- MXML lexer +* Norman Richards -- JSON lexer +* Corey Richardson -- Rust lexer updates +* Lubomir Rintel -- GoodData MAQL and CL lexers +* Andre Roberge -- Tango style +* Konrad Rudolph -- LaTeX formatter enhancements +* Mario Ruggier -- Evoque lexers +* Stou Sandalski -- NumPy, FORTRAN, tcsh and XSLT lexers +* Matteo Sasso -- Common Lisp lexer +* Joe Schafer -- Ada lexer +* Ken Schutte -- Matlab lexers +* Tassilo Schweyer -- Io, MOOCode lexers +* Ted Shaw -- AutoIt lexer +* Joerg Sieker -- ABAP lexer +* Robert Simmons -- Standard ML lexer +* Kirill Simonov -- YAML lexer +* Alexander Smishlajev -- Visual FoxPro lexer +* Steve Spigarelli -- XQuery lexer +* Jerome St-Louis -- eC lexer +* James Strachan -- Kotlin lexer +* Tom Stuart -- Treetop lexer +* Tiberius Teng -- default style overhaul +* Jeremy Thurgood -- Erlang, Squid config lexers +* Brian Tiffin -- OpenCOBOL lexer +* Bob Tolbert -- Hy lexer +* Erick Tryzelaar -- Felix lexer +* Alexander Udalov -- Kotlin lexer improvements +* Thomas Van Doren -- Chapel lexer +* Daniele Varrazzo -- PostgreSQL lexers +* Abe Voelker -- OpenEdge ABL lexer +* Pepijn de Vos -- HTML formatter CTags support +* Whitney Young -- ObjectiveC lexer +* Matthias Vallentin -- Bro lexer +* Linh Vu Hong -- RSL lexer +* Nathan Weizenbaum -- Haml and Sass lexers +* Dietmar Winkler -- Modelica lexer +* Nils Winter -- Smalltalk lexer +* Davy Wybiral -- Clojure lexer +* Diego Zamboni -- CFengine3 lexer +* Enrique Zamudio -- Ceylon lexer +* Alex Zimin -- Nemerle lexer +* Rob Zimmerman -- Kal lexer + +Many thanks for all contributions! diff --git a/node_modules/pygmentize-bundled/vendor/pygments/CHANGES b/node_modules/pygmentize-bundled/vendor/pygments/CHANGES new file mode 100644 index 000000000..8459e05ab --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/CHANGES @@ -0,0 +1,941 @@ +Pygments changelog +================== + +Issue numbers refer to the tracker at +, +pull request numbers to the requests at +. + +Version 2.0 +----------- +(under development) + +- Dropped Python 2.4 and 2.5 compatibility. This is in favor of single-source + compatibility between Python 2.6, 2.7 and 3.3+. + +- New website and documentation based on Sphinx (finally!) + +- Lexers added: + + * Clay (PR#184) + * Perl 6 (PR#181) + * Swig (PR#168) + * nesC (PR#166) + * BlitzBasic (PR#197) + * EBNF (PR#193) + * Igor Pro (PR#172) + * Rexx (PR#199) + * Agda and Literate Agda (PR#203) + * Mathematica (PR#245) + * Nix (PR#267) + * Pike (PR#237) + * Hy (PR#238) + * Chapel (PR#256) + * Kal (PR#233) + * Eiffel (PR#273) + * Cirru (PR#275) + * ColdFusion CFC (PR#283) + * Idris (PR#210) + * Intel objdump (PR#279) + * MaskJS (PR#280) + * Inform 6/7 (PR#281) + * MQL (PR#285) + * APL (#969) + +- New styles: "xcode" and "igor", similar to the default highlighting of + the respective IDEs. + +- Updated the Makefile lexer to yield a little more useful highlighting. + +- Lexer aliases passed to ``get_lexer_by_name()`` are now case-insensitive. + +- File name matching in lexers and formatters will now use a regex cache + for speed (PR#205). + +- Pygments will now recognize "vim" modelines when guessing the lexer for + a file based on content (PR#118). + +- The NameHighlightFilter now works with any Name.* token type (#790). + +- Python 3 lexer: add new exceptions from PEP 3151. + +- Opa lexer: add new keywords (PR#170). + +- Julia lexer: add keywords and underscore-separated number + literals (PR#176). + +- Lasso lexer: fix method highlighting, update builtins. Fix + guessing so that plain XML isn't always taken as Lasso (PR#163). + +- Objective C/C++ lexers: allow "@" prefixing any expression (#871). + +- Ruby lexer: fix lexing of Name::Space tokens (#860) and of symbols + in hashes (#873). + +- Stan lexer: update for version 1.3.0 of the language (PR#162). + +- JavaScript lexer: add the "yield" keyword (PR#196). + +- HTTP lexer: support for PATCH method (PR#190). + +- Koka lexer: update to newest language spec (PR#201). + +- Haxe lexer: rewrite and support for Haxe 3 (PR#174). + +- Prolog lexer: add different kinds of numeric literals (#864). + +- F# lexer: rewrite with newest spec for F# 3.0 (#842), fix a bug with + dotted chains (#948). + +- Kotlin lexer: general update (PR#271). + +- Rebol lexer: fix comment detection and analyse_text (PR#261). + +- Stan lexer: update to v2.0.1 (PR#255). + +- LLVM lexer: update keywords to v3.4 (PR#258). + +- PHP lexer: add new keywords and binary literals (PR#222). + +- external/markdown-processor.py updated to newest python-markdown (PR#221). + +- CSS lexer: some highlighting order fixes (PR#231). + +- Ceylon lexer: fix parsing of nested multiline comments (#915). + +- C family lexers: fix parsing of indented preprocessor directives (#944). + +- Rust lexer: update to 0.9 language version (PR#270). + + +Version 1.6 +----------- +(released Feb 3, 2013) + +- Lexers added: + + * Dylan console (PR#149) + * Logos (PR#150) + * Shell sessions (PR#158) + +- Fix guessed lexers not receiving lexer options (#838). + +- Fix unquoted HTML attribute lexing in Opa (#841). + +- Fixes to the Dart lexer (PR#160). + + +Version 1.6rc1 +-------------- +(released Jan 9, 2013) + +- Lexers added: + + * AspectJ (PR#90) + * AutoIt (PR#122) + * BUGS-like languages (PR#89) + * Ceylon (PR#86) + * Croc (new name for MiniD) + * CUDA (PR#75) + * Dg (PR#116) + * IDL (PR#115) + * Jags (PR#89) + * Julia (PR#61) + * Kconfig (#711) + * Lasso (PR#95, PR#113) + * LiveScript (PR#84) + * Monkey (PR#117) + * Mscgen (PR#80) + * NSIS scripts (PR#136) + * OpenCOBOL (PR#72) + * QML (PR#123) + * Puppet (PR#133) + * Racket (PR#94) + * Rdoc (PR#99) + * Robot Framework (PR#137) + * RPM spec files (PR#124) + * Rust (PR#67) + * Smali (Dalvik assembly) + * SourcePawn (PR#39) + * Stan (PR#89) + * Treetop (PR#125) + * TypeScript (PR#114) + * VGL (PR#12) + * Visual FoxPro (#762) + * Windows Registry (#819) + * Xtend (PR#68) + +- The HTML formatter now supports linking to tags using CTags files, when the + python-ctags package is installed (PR#87). + +- The HTML formatter now has a "linespans" option that wraps every line in a + tag with a specific id (PR#82). + +- When deriving a lexer from another lexer with token definitions, definitions + for states not in the child lexer are now inherited. If you override a state + in the child lexer, an "inherit" keyword has been added to insert the base + state at that position (PR#141). + +- The C family lexers now inherit token definitions from a common base class, + removing code duplication (PR#141). + +- Use "colorama" on Windows for console color output (PR#142). + +- Fix Template Haskell highlighting (PR#63). + +- Fix some S/R lexer errors (PR#91). + +- Fix a bug in the Prolog lexer with names that start with 'is' (#810). + +- Rewrite Dylan lexer, add Dylan LID lexer (PR#147). + +- Add a Java quickstart document (PR#146). + +- Add a "external/autopygmentize" file that can be used as .lessfilter (#802). + + +Version 1.5 +----------- +(codename Zeitdilatation, released Mar 10, 2012) + +- Lexers added: + + * Awk (#630) + * Fancy (#633) + * PyPy Log + * eC + * Nimrod + * Nemerle (#667) + * F# (#353) + * Groovy (#501) + * PostgreSQL (#660) + * DTD + * Gosu (#634) + * Octave (PR#22) + * Standard ML (PR#14) + * CFengine3 (#601) + * Opa (PR#37) + * HTTP sessions (PR#42) + * JSON (PR#31) + * SNOBOL (PR#30) + * MoonScript (PR#43) + * ECL (PR#29) + * Urbiscript (PR#17) + * OpenEdge ABL (PR#27) + * SystemVerilog (PR#35) + * Coq (#734) + * PowerShell (#654) + * Dart (#715) + * Fantom (PR#36) + * Bro (PR#5) + * NewLISP (PR#26) + * VHDL (PR#45) + * Scilab (#740) + * Elixir (PR#57) + * Tea (PR#56) + * Kotlin (PR#58) + +- Fix Python 3 terminal highlighting with pygmentize (#691). + +- In the LaTeX formatter, escape special &, < and > chars (#648). + +- In the LaTeX formatter, fix display problems for styles with token + background colors (#670). + +- Enhancements to the Squid conf lexer (#664). + +- Several fixes to the reStructuredText lexer (#636). + +- Recognize methods in the ObjC lexer (#638). + +- Fix Lua "class" highlighting: it does not have classes (#665). + +- Fix degenerate regex in Scala lexer (#671) and highlighting bugs (#713, 708). + +- Fix number pattern order in Ocaml lexer (#647). + +- Fix generic type highlighting in ActionScript 3 (#666). + +- Fixes to the Clojure lexer (PR#9). + +- Fix degenerate regex in Nemerle lexer (#706). + +- Fix infinite looping in CoffeeScript lexer (#729). + +- Fix crashes and analysis with ObjectiveC lexer (#693, #696). + +- Add some Fortran 2003 keywords. + +- Fix Boo string regexes (#679). + +- Add "rrt" style (#727). + +- Fix infinite looping in Darcs Patch lexer. + +- Lots of misc fixes to character-eating bugs and ordering problems in many + different lexers. + + +Version 1.4 +----------- +(codename Unschärfe, released Jan 03, 2011) + +- Lexers added: + + * Factor (#520) + * PostScript (#486) + * Verilog (#491) + * BlitzMax Basic (#478) + * Ioke (#465) + * Java properties, split out of the INI lexer (#445) + * Scss (#509) + * Duel/JBST + * XQuery (#617) + * Mason (#615) + * GoodData (#609) + * SSP (#473) + * Autohotkey (#417) + * Google Protocol Buffers + * Hybris (#506) + +- Do not fail in analyse_text methods (#618). + +- Performance improvements in the HTML formatter (#523). + +- With the ``noclasses`` option in the HTML formatter, some styles + present in the stylesheet were not added as inline styles. + +- Four fixes to the Lua lexer (#480, #481, #482, #497). + +- More context-sensitive Gherkin lexer with support for more i18n translations. + +- Support new OO keywords in Matlab lexer (#521). + +- Small fix in the CoffeeScript lexer (#519). + +- A bugfix for backslashes in ocaml strings (#499). + +- Fix unicode/raw docstrings in the Python lexer (#489). + +- Allow PIL to work without PIL.pth (#502). + +- Allow seconds as a unit in CSS (#496). + +- Support ``application/javascript`` as a JavaScript mime type (#504). + +- Support `Offload `_ C++ Extensions as + keywords in the C++ lexer (#484). + +- Escape more characters in LaTeX output (#505). + +- Update Haml/Sass lexers to version 3 (#509). + +- Small PHP lexer string escaping fix (#515). + +- Support comments before preprocessor directives, and unsigned/ + long long literals in C/C++ (#613, #616). + +- Support line continuations in the INI lexer (#494). + +- Fix lexing of Dylan string and char literals (#628). + +- Fix class/procedure name highlighting in VB.NET lexer (#624). + + +Version 1.3.1 +------------- +(bugfix release, released Mar 05, 2010) + +- The ``pygmentize`` script was missing from the distribution. + + +Version 1.3 +----------- +(codename Schneeglöckchen, released Mar 01, 2010) + +- Added the ``ensurenl`` lexer option, which can be used to suppress the + automatic addition of a newline to the lexer input. + +- Lexers added: + + * Ada + * Coldfusion + * Modula-2 + * Haxe + * R console + * Objective-J + * Haml and Sass + * CoffeeScript + +- Enhanced reStructuredText highlighting. + +- Added support for PHP 5.3 namespaces in the PHP lexer. + +- Added a bash completion script for `pygmentize`, to the external/ + directory (#466). + +- Fixed a bug in `do_insertions()` used for multi-lexer languages. + +- Fixed a Ruby regex highlighting bug (#476). + +- Fixed regex highlighting bugs in Perl lexer (#258). + +- Add small enhancements to the C lexer (#467) and Bash lexer (#469). + +- Small fixes for the Tcl, Debian control file, Nginx config, + Smalltalk, Objective-C, Clojure, Lua lexers. + +- Gherkin lexer: Fixed single apostrophe bug and added new i18n keywords. + + +Version 1.2.2 +------------- +(bugfix release, released Jan 02, 2010) + +* Removed a backwards incompatibility in the LaTeX formatter that caused + Sphinx to produce invalid commands when writing LaTeX output (#463). + +* Fixed a forever-backtracking regex in the BashLexer (#462). + + +Version 1.2.1 +------------- +(bugfix release, released Jan 02, 2010) + +* Fixed mishandling of an ellipsis in place of the frames in a Python + console traceback, resulting in clobbered output. + + +Version 1.2 +----------- +(codename Neujahr, released Jan 01, 2010) + +- Dropped Python 2.3 compatibility. + +- Lexers added: + + * Asymptote + * Go + * Gherkin (Cucumber) + * CMake + * Ooc + * Coldfusion + * Haxe + * R console + +- Added options for rendering LaTeX in source code comments in the + LaTeX formatter (#461). + +- Updated the Logtalk lexer. + +- Added `line_number_start` option to image formatter (#456). + +- Added `hl_lines` and `hl_color` options to image formatter (#457). + +- Fixed the HtmlFormatter's handling of noclasses=True to not output any + classes (#427). + +- Added the Monokai style (#453). + +- Fixed LLVM lexer identifier syntax and added new keywords (#442). + +- Fixed the PythonTracebackLexer to handle non-traceback data in header or + trailer, and support more partial tracebacks that start on line 2 (#437). + +- Fixed the CLexer to not highlight ternary statements as labels. + +- Fixed lexing of some Ruby quoting peculiarities (#460). + +- A few ASM lexer fixes (#450). + + +Version 1.1.1 +------------- +(bugfix release, released Sep 15, 2009) + +- Fixed the BBCode lexer (#435). + +- Added support for new Jinja2 keywords. + +- Fixed test suite failures. + +- Added Gentoo-specific suffixes to Bash lexer. + + +Version 1.1 +----------- +(codename Brillouin, released Sep 11, 2009) + +- Ported Pygments to Python 3. This needed a few changes in the way + encodings are handled; they may affect corner cases when used with + Python 2 as well. + +- Lexers added: + + * Antlr/Ragel, thanks to Ana Nelson + * (Ba)sh shell + * Erlang shell + * GLSL + * Prolog + * Evoque + * Modelica + * Rebol + * MXML + * Cython + * ABAP + * ASP.net (VB/C#) + * Vala + * Newspeak + +- Fixed the LaTeX formatter's output so that output generated for one style + can be used with the style definitions of another (#384). + +- Added "anchorlinenos" and "noclobber_cssfile" (#396) options to HTML + formatter. + +- Support multiline strings in Lua lexer. + +- Rewrite of the JavaScript lexer by Pumbaa80 to better support regular + expression literals (#403). + +- When pygmentize is asked to highlight a file for which multiple lexers + match the filename, use the analyse_text guessing engine to determine the + winner (#355). + +- Fixed minor bugs in the JavaScript lexer (#383), the Matlab lexer (#378), + the Scala lexer (#392), the INI lexer (#391), the Clojure lexer (#387) + and the AS3 lexer (#389). + +- Fixed three Perl heredoc lexing bugs (#379, #400, #422). + +- Fixed a bug in the image formatter which misdetected lines (#380). + +- Fixed bugs lexing extended Ruby strings and regexes. + +- Fixed a bug when lexing git diffs. + +- Fixed a bug lexing the empty commit in the PHP lexer (#405). + +- Fixed a bug causing Python numbers to be mishighlighted as floats (#397). + +- Fixed a bug when backslashes are used in odd locations in Python (#395). + +- Fixed various bugs in Matlab and S-Plus lexers, thanks to Winston Chang (#410, + #411, #413, #414) and fmarc (#419). + +- Fixed a bug in Haskell single-line comment detection (#426). + +- Added new-style reStructuredText directive for docutils 0.5+ (#428). + + +Version 1.0 +----------- +(codename Dreiundzwanzig, released Nov 23, 2008) + +- Don't use join(splitlines()) when converting newlines to ``\n``, + because that doesn't keep all newlines at the end when the + ``stripnl`` lexer option is False. + +- Added ``-N`` option to command-line interface to get a lexer name + for a given filename. + +- Added Tango style, written by Andre Roberge for the Crunchy project. + +- Added Python3TracebackLexer and ``python3`` option to + PythonConsoleLexer. + +- Fixed a few bugs in the Haskell lexer. + +- Fixed PythonTracebackLexer to be able to recognize SyntaxError and + KeyboardInterrupt (#360). + +- Provide one formatter class per image format, so that surprises like:: + + pygmentize -f gif -o foo.gif foo.py + + creating a PNG file are avoided. + +- Actually use the `font_size` option of the image formatter. + +- Fixed numpy lexer that it doesn't listen for `*.py` any longer. + +- Fixed HTML formatter so that text options can be Unicode + strings (#371). + +- Unified Diff lexer supports the "udiff" alias now. + +- Fixed a few issues in Scala lexer (#367). + +- RubyConsoleLexer now supports simple prompt mode (#363). + +- JavascriptLexer is smarter about what constitutes a regex (#356). + +- Add Applescript lexer, thanks to Andreas Amann (#330). + +- Make the codetags more strict about matching words (#368). + +- NginxConfLexer is a little more accurate on mimetypes and + variables (#370). + + +Version 0.11.1 +-------------- +(released Aug 24, 2008) + +- Fixed a Jython compatibility issue in pygments.unistring (#358). + + +Version 0.11 +------------ +(codename Straußenei, released Aug 23, 2008) + +Many thanks go to Tim Hatch for writing or integrating most of the bug +fixes and new features. + +- Lexers added: + + * Nasm-style assembly language, thanks to delroth + * YAML, thanks to Kirill Simonov + * ActionScript 3, thanks to Pierre Bourdon + * Cheetah/Spitfire templates, thanks to Matt Good + * Lighttpd config files + * Nginx config files + * Gnuplot plotting scripts + * Clojure + * POV-Ray scene files + * Sqlite3 interactive console sessions + * Scala source files, thanks to Krzysiek Goj + +- Lexers improved: + + * C lexer highlights standard library functions now and supports C99 + types. + * Bash lexer now correctly highlights heredocs without preceding + whitespace. + * Vim lexer now highlights hex colors properly and knows a couple + more keywords. + * Irc logs lexer now handles xchat's default time format (#340) and + correctly highlights lines ending in ``>``. + * Support more delimiters for perl regular expressions (#258). + * ObjectiveC lexer now supports 2.0 features. + +- Added "Visual Studio" style. + +- Updated markdown processor to Markdown 1.7. + +- Support roman/sans/mono style defs and use them in the LaTeX + formatter. + +- The RawTokenFormatter is no longer registered to ``*.raw`` and it's + documented that tokenization with this lexer may raise exceptions. + +- New option ``hl_lines`` to HTML formatter, to highlight certain + lines. + +- New option ``prestyles`` to HTML formatter. + +- New option *-g* to pygmentize, to allow lexer guessing based on + filetext (can be slowish, so file extensions are still checked + first). + +- ``guess_lexer()`` now makes its decision much faster due to a cache + of whether data is xml-like (a check which is used in several + versions of ``analyse_text()``. Several lexers also have more + accurate ``analyse_text()`` now. + + +Version 0.10 +------------ +(codename Malzeug, released May 06, 2008) + +- Lexers added: + + * Io + * Smalltalk + * Darcs patches + * Tcl + * Matlab + * Matlab sessions + * FORTRAN + * XSLT + * tcsh + * NumPy + * Python 3 + * S, S-plus, R statistics languages + * Logtalk + +- In the LatexFormatter, the *commandprefix* option is now by default + 'PY' instead of 'C', since the latter resulted in several collisions + with other packages. Also, the special meaning of the *arg* + argument to ``get_style_defs()`` was removed. + +- Added ImageFormatter, to format code as PNG, JPG, GIF or BMP. + (Needs the Python Imaging Library.) + +- Support doc comments in the PHP lexer. + +- Handle format specifications in the Perl lexer. + +- Fix comment handling in the Batch lexer. + +- Add more file name extensions for the C++, INI and XML lexers. + +- Fixes in the IRC and MuPad lexers. + +- Fix function and interface name highlighting in the Java lexer. + +- Fix at-rule handling in the CSS lexer. + +- Handle KeyboardInterrupts gracefully in pygmentize. + +- Added BlackWhiteStyle. + +- Bash lexer now correctly highlights math, does not require + whitespace after semicolons, and correctly highlights boolean + operators. + +- Makefile lexer is now capable of handling BSD and GNU make syntax. + + +Version 0.9 +----------- +(codename Herbstzeitlose, released Oct 14, 2007) + +- Lexers added: + + * Erlang + * ActionScript + * Literate Haskell + * Common Lisp + * Various assembly languages + * Gettext catalogs + * Squid configuration + * Debian control files + * MySQL-style SQL + * MOOCode + +- Lexers improved: + + * Greatly improved the Haskell and OCaml lexers. + * Improved the Bash lexer's handling of nested constructs. + * The C# and Java lexers exhibited abysmal performance with some + input code; this should now be fixed. + * The IRC logs lexer is now able to colorize weechat logs too. + * The Lua lexer now recognizes multi-line comments. + * Fixed bugs in the D and MiniD lexer. + +- The encoding handling of the command line mode (pygmentize) was + enhanced. You shouldn't get UnicodeErrors from it anymore if you + don't give an encoding option. + +- Added a ``-P`` option to the command line mode which can be used to + give options whose values contain commas or equals signs. + +- Added 256-color terminal formatter. + +- Added an experimental SVG formatter. + +- Added the ``lineanchors`` option to the HTML formatter, thanks to + Ian Charnas for the idea. + +- Gave the line numbers table a CSS class in the HTML formatter. + +- Added a Vim 7-like style. + + +Version 0.8.1 +------------- +(released Jun 27, 2007) + +- Fixed POD highlighting in the Ruby lexer. + +- Fixed Unicode class and namespace name highlighting in the C# lexer. + +- Fixed Unicode string prefix highlighting in the Python lexer. + +- Fixed a bug in the D and MiniD lexers. + +- Fixed the included MoinMoin parser. + + +Version 0.8 +----------- +(codename Maikäfer, released May 30, 2007) + +- Lexers added: + + * Haskell, thanks to Adam Blinkinsop + * Redcode, thanks to Adam Blinkinsop + * D, thanks to Kirk McDonald + * MuPad, thanks to Christopher Creutzig + * MiniD, thanks to Jarrett Billingsley + * Vim Script, by Tim Hatch + +- The HTML formatter now has a second line-numbers mode in which it + will just integrate the numbers in the same ``
`` tag as the
+  code.
+
+- The `CSharpLexer` now is Unicode-aware, which means that it has an
+  option that can be set so that it correctly lexes Unicode
+  identifiers allowed by the C# specs.
+
+- Added a `RaiseOnErrorTokenFilter` that raises an exception when the
+  lexer generates an error token, and a `VisibleWhitespaceFilter` that
+  converts whitespace (spaces, tabs, newlines) into visible
+  characters.
+
+- Fixed the `do_insertions()` helper function to yield correct
+  indices.
+
+- The ReST lexer now automatically highlights source code blocks in
+  ".. sourcecode:: language" and ".. code:: language" directive
+  blocks.
+
+- Improved the default style (thanks to Tiberius Teng). The old
+  default is still available as the "emacs" style (which was an alias
+  before).
+
+- The `get_style_defs` method of HTML formatters now uses the
+  `cssclass` option as the default selector if it was given.
+
+- Improved the ReST and Bash lexers a bit.
+
+- Fixed a few bugs in the Makefile and Bash lexers, thanks to Tim
+  Hatch.
+
+- Fixed a bug in the command line code that disallowed ``-O`` options
+  when using the ``-S`` option.
+
+- Fixed a bug in the `RawTokenFormatter`.
+
+
+Version 0.7.1
+-------------
+(released Feb 15, 2007)
+
+- Fixed little highlighting bugs in the Python, Java, Scheme and
+  Apache Config lexers.
+
+- Updated the included manpage.
+
+- Included a built version of the documentation in the source tarball.
+
+
+Version 0.7
+-----------
+(codename Faschingskrapfn, released Feb 14, 2007)
+
+- Added a MoinMoin parser that uses Pygments. With it, you get
+  Pygments highlighting in Moin Wiki pages.
+
+- Changed the exception raised if no suitable lexer, formatter etc. is
+  found in one of the `get_*_by_*` functions to a custom exception,
+  `pygments.util.ClassNotFound`. It is, however, a subclass of
+  `ValueError` in order to retain backwards compatibility.
+
+- Added a `-H` command line option which can be used to get the
+  docstring of a lexer, formatter or filter.
+
+- Made the handling of lexers and formatters more consistent. The
+  aliases and filename patterns of formatters are now attributes on
+  them.
+
+- Added an OCaml lexer, thanks to Adam Blinkinsop.
+
+- Made the HTML formatter more flexible, and easily subclassable in
+  order to make it easy to implement custom wrappers, e.g. alternate
+  line number markup. See the documentation.
+
+- Added an `outencoding` option to all formatters, making it possible
+  to override the `encoding` (which is used by lexers and formatters)
+  when using the command line interface. Also, if using the terminal
+  formatter and the output file is a terminal and has an encoding
+  attribute, use it if no encoding is given.
+
+- Made it possible to just drop style modules into the `styles`
+  subpackage of the Pygments installation.
+
+- Added a "state" keyword argument to the `using` helper.
+
+- Added a `commandprefix` option to the `LatexFormatter` which allows
+  to control how the command names are constructed.
+
+- Added quite a few new lexers, thanks to Tim Hatch:
+
+  * Java Server Pages
+  * Windows batch files
+  * Trac Wiki markup
+  * Python tracebacks
+  * ReStructuredText
+  * Dylan
+  * and the Befunge esoteric programming language (yay!)
+
+- Added Mako lexers by Ben Bangert.
+
+- Added "fruity" style, another dark background originally vim-based
+  theme.
+
+- Added sources.list lexer by Dennis Kaarsemaker.
+
+- Added token stream filters, and a pygmentize option to use them.
+
+- Changed behavior of `in` Operator for tokens.
+
+- Added mimetypes for all lexers.
+
+- Fixed some problems lexing Python strings.
+
+- Fixed tickets: #167, #178, #179, #180, #185, #201.
+
+
+Version 0.6
+-----------
+(codename Zimtstern, released Dec 20, 2006)
+
+- Added option for the HTML formatter to write the CSS to an external
+  file in "full document" mode.
+
+- Added RTF formatter.
+
+- Added Bash and Apache configuration lexers (thanks to Tim Hatch).
+
+- Improved guessing methods for various lexers.
+
+- Added `@media` support to CSS lexer (thanks to Tim Hatch).
+
+- Added a Groff lexer (thanks to Tim Hatch).
+
+- License change to BSD.
+
+- Added lexers for the Myghty template language.
+
+- Added a Scheme lexer (thanks to Marek Kubica).
+
+- Added some functions to iterate over existing lexers, formatters and
+  lexers.
+
+- The HtmlFormatter's `get_style_defs()` can now take a list as an
+  argument to generate CSS with multiple prefixes.
+
+- Support for guessing input encoding added.
+
+- Encoding support added: all processing is now done with Unicode
+  strings, input and output are converted from and optionally to byte
+  strings (see the ``encoding`` option of lexers and formatters).
+
+- Some improvements in the C(++) lexers handling comments and line
+  continuations.
+
+
+Version 0.5.1
+-------------
+(released Oct 30, 2006)
+
+- Fixed traceback in ``pygmentize -L`` (thanks to Piotr Ozarowski).
+
+
+Version 0.5
+-----------
+(codename PyKleur, released Oct 30, 2006)
+
+- Initial public release.
diff --git a/node_modules/pygmentize-bundled/vendor/pygments/LICENSE b/node_modules/pygmentize-bundled/vendor/pygments/LICENSE
new file mode 100644
index 000000000..641c8e8e7
--- /dev/null
+++ b/node_modules/pygmentize-bundled/vendor/pygments/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2006-2014 by the respective authors (see AUTHORS file).
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/node_modules/pygmentize-bundled/vendor/pygments/MANIFEST.in b/node_modules/pygmentize-bundled/vendor/pygments/MANIFEST.in
new file mode 100644
index 000000000..cfec4e94a
--- /dev/null
+++ b/node_modules/pygmentize-bundled/vendor/pygments/MANIFEST.in
@@ -0,0 +1,6 @@
+include pygmentize
+include external/*
+include Makefile CHANGES LICENSE AUTHORS TODO ez_setup.py
+recursive-include tests *
+recursive-include doc *
+recursive-include scripts *
diff --git a/node_modules/pygmentize-bundled/vendor/pygments/Makefile b/node_modules/pygmentize-bundled/vendor/pygments/Makefile
new file mode 100644
index 000000000..e28c90c74
--- /dev/null
+++ b/node_modules/pygmentize-bundled/vendor/pygments/Makefile
@@ -0,0 +1,56 @@
+#
+# Makefile for Pygments
+# ~~~~~~~~~~~~~~~~~~~~~
+#
+# Combines scripts for common tasks.
+#
+# :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS.
+# :license: BSD, see LICENSE for details.
+#
+
+PYTHON ?= python
+
+export PYTHONPATH = $(shell echo "$$PYTHONPATH"):$(shell python -c 'import os; print ":".join(os.path.abspath(line.strip()) for line in file("PYTHONPATH"))' 2>/dev/null)
+
+.PHONY: all check clean clean-pyc codetags docs mapfiles \
+	pylint reindent test test-coverage
+
+all: clean-pyc check test
+
+check:
+	@$(PYTHON) scripts/detect_missing_analyse_text.py || true
+	@$(PYTHON) scripts/check_sources.py -i build -i dist -i pygments/lexers/_mapping.py \
+		   -i docs/build -i pygments/formatters/_mapping.py -i pygments/unistring.py \
+		   -i pygments/lexers/_vimbuiltins.py
+
+clean: clean-pyc
+	-rm -rf build
+	-rm -f codetags.html
+
+clean-pyc:
+	find . -name '*.pyc' -exec rm -f {} +
+	find . -name '*.pyo' -exec rm -f {} +
+	find . -name '*~' -exec rm -f {} +
+
+codetags:
+	@$(PYTHON) scripts/find_codetags.py -i tests/examplefiles -i scripts/pylintrc \
+		   -i scripts/find_codetags.py -o codetags.html .
+
+docs:
+	make -C doc html
+
+mapfiles:
+	(cd pygments/lexers; $(PYTHON) _mapping.py)
+	(cd pygments/formatters; $(PYTHON) _mapping.py)
+
+pylint:
+	@pylint --rcfile scripts/pylintrc pygments
+
+reindent:
+	@$(PYTHON) scripts/reindent.py -r -B .
+
+test:
+	@$(PYTHON) tests/run.py $(TEST)
+
+test-coverage:
+	@$(PYTHON) tests/run.py -C $(TEST)
diff --git a/node_modules/pygmentize-bundled/vendor/pygments/TODO b/node_modules/pygmentize-bundled/vendor/pygments/TODO
new file mode 100644
index 000000000..3ff63a3f5
--- /dev/null
+++ b/node_modules/pygmentize-bundled/vendor/pygments/TODO
@@ -0,0 +1,15 @@
+Todo
+====
+
+- suggested new lexers
+  * IPython sessions
+
+- lexers that need work:
+  * review perl lexer (numerous bugs, but so far no one had complaints ;)
+  * readd property support for C# lexer? that is, find a regex that doesn't
+    backtrack to death...
+  * add support for function name highlighting to C++ lexer
+
+- allow "overlay" token types to highlight specials: nth line, a word etc.
+
+- pygmentize option presets, more sophisticated method to output styles?
diff --git a/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygmentize b/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygmentize
new file mode 100755
index 000000000..8c1c63a8f
--- /dev/null
+++ b/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygmentize
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+
+import sys, pygments.cmdline
+try:
+    sys.exit(pygments.cmdline.main(sys.argv))
+except KeyboardInterrupt:
+    sys.exit(1)
diff --git a/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/__init__.py b/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/__init__.py
new file mode 100644
index 000000000..a47f686ef
--- /dev/null
+++ b/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/__init__.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+"""
+    Pygments
+    ~~~~~~~~
+
+    Pygments is a syntax highlighting package written in Python.
+
+    It is a generic syntax highlighter for general use in all kinds of software
+    such as forum systems, wikis or other applications that need to prettify
+    source code. Highlights are:
+
+    * a wide range of common languages and markup formats is supported
+    * special attention is paid to details, increasing quality by a fair amount
+    * support for new languages and formats are added easily
+    * a number of output formats, presently HTML, LaTeX, RTF, SVG, all image
+      formats that PIL supports, and ANSI sequences
+    * it is usable as a command-line tool and as a library
+    * ... and it highlights even Brainfuck!
+
+    The `Pygments tip`_ is installable with ``easy_install Pygments==dev``.
+
+    .. _Pygments tip:
+       http://bitbucket.org/birkenfeld/pygments-main/get/tip.zip#egg=Pygments-dev
+
+    :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+__version__ = '2.0pre'
+__docformat__ = 'restructuredtext'
+
+__all__ = ['lex', 'format', 'highlight']
+
+
+import sys
+
+from pygments.util import StringIO, BytesIO
+
+
+def lex(code, lexer):
+    """
+    Lex ``code`` with ``lexer`` and return an iterable of tokens.
+    """
+    try:
+        return lexer.get_tokens(code)
+    except TypeError as err:
+        if isinstance(err.args[0], str) and \
+           'unbound method get_tokens' in err.args[0]:
+            raise TypeError('lex() argument must be a lexer instance, '
+                            'not a class')
+        raise
+
+
+def format(tokens, formatter, outfile=None):
+    """
+    Format a tokenlist ``tokens`` with the formatter ``formatter``.
+
+    If ``outfile`` is given and a valid file object (an object
+    with a ``write`` method), the result will be written to it, otherwise
+    it is returned as a string.
+    """
+    try:
+        if not outfile:
+            #print formatter, 'using', formatter.encoding
+            realoutfile = formatter.encoding and BytesIO() or StringIO()
+            formatter.format(tokens, realoutfile)
+            return realoutfile.getvalue()
+        else:
+            formatter.format(tokens, outfile)
+    except TypeError as err:
+        if isinstance(err.args[0], str) and \
+           'unbound method format' in err.args[0]:
+            raise TypeError('format() argument must be a formatter instance, '
+                            'not a class')
+        raise
+
+
+def highlight(code, lexer, formatter, outfile=None):
+    """
+    Lex ``code`` with ``lexer`` and format it with the formatter ``formatter``.
+
+    If ``outfile`` is given and a valid file object (an object
+    with a ``write`` method), the result will be written to it, otherwise
+    it is returned as a string.
+    """
+    return format(lex(code, lexer), formatter, outfile)
+
+
+if __name__ == '__main__':
+    from pygments.cmdline import main
+    sys.exit(main(sys.argv))
diff --git a/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/__init__.pyc b/node_modules/pygmentize-bundled/vendor/pygments/build-2.7/pygments/__init__.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..245c274d92e7432217e92cb0335ca2f370e781a5
GIT binary patch
literal 3741
zcmds4TW=dh6h3RGPU@y<%cX$&GKiN@Id-WkkOD=}QfQ=*B0B{X9@gXCu|4tLn3+v#
zRCu8L2zWreAo0Yn;|IWZW^9MMcm%BOWOgoR&N=ga-`O^Qy4e2V$L9_cTKt;$`xYMi
zEt-_*2yH}15v2_}YEaswbdAz;G-=Wi`YlS=DO;l>45Gh5**VHvbkw4JosQNiO3%|*
zu(HAH(l&hsTW#OJ;QJRyZBn{Pvj&-OyormHU8H=AjAgZU&^g|q(Ui^Z?~n<=5KkiyOjCm)Hao=h`5P8SnV$z&!cN}L+)
zoGOGaV9!mn=xvrgrk)NX9zs5z#h&PT`-;wfua)o$r}hZAJsVKx`{58vPKh<$me
zKJJMA;kz9%`0%}szZ;z+bnl5+?hI-EU~hjJI>O=9ynQg(6IOj%t0GYWW7mcDsHm+R
zWpI$O#c9RzolF-B_f#TN*zBh=Ju=cPeeZU=ehMa5K(s=g0DE_g)Wx_?W-o@zJDe&p
zT%ubzT@7Q-x-P5(!2H>#+D*l9i0sVc#rTR3w{NHFWH?*^8OO%IwzazmUre2=c6+^%
zb|W0ET(>k6yqTFQ#wtsD)q-9-IlSvllvyJ3Ty0e9)FbDb7|hV&bpcoIJi4po>!0yE*lu9V
zZJ-%A1N`niaO-%vGk41FJxF+#4V}Yt7mppInO~vD5gijfCYGncN5uiHxrkJcuSDL)*7+Wz_xo-%l4$RQ22fdYY`P8kmpu*8+PP8%|-VT$YvXzF4FN`n3hikCvf
zTpSkKTbPB_?U$h?lbYpKlz}~IAOncs`nA4MJt8DLBo=BS*UAdhR6eY1c$rM~t5XWAD<6>;8Gb~)7UVo-`
zMo3Yn(jF+9mS#C)d!t%s>CVmWYiC0-NT^*LcdL0nTDWPsTG3iFx)NQAu0~Hsml_F&
z$bqfk^gUkY4;U5p%>}5;H3r2KqUuEgjL`YK>8H>FasUhPg+IqY6;R7a3^Q1ZnE=Lf
z9*o}sjB5a6iyot#q8u|AH#`_odI84OD1-4ELel>hj6cC!55{+W!4NXwE7L&8a2O!8
zL??57K|2WcaJcHPlxc5_VaWJcXN+km+(fe+dI1$DC?l!hIZ=*|RpP`pupPSI2hRZs
z6I{aCKtS`$9WOJGgF15{3Mw+dyDamlq}p{twLJwgyrrP(fj}rZUc3QFfa%x7c^1L{
zjyNGE`#NSq_s@B=3jMFR!@A@(2(_k6ac-Xh(r1SBSNa5AAt$x!vp)4%vHHBP&$J5c
zW2Fn1;F-5N)+^c~(e45kp;l*$_x?rRj_1EXEzZTOcWX8O1nh
z%jYhyWx;d!7kT=CSzd&hM@@( | -g] [-F [:]] [-f ]
+          [-O ] [-P ] [-o ] []
+
+       %s -S 
+
+
+

%(title)s

+ +''' + +DOC_HEADER_EXTERNALCSS = '''\ + + + + + %(title)s + + + + +

%(title)s

+ +''' + +DOC_FOOTER = '''\ + + +''' + + +class HtmlFormatter(Formatter): + r""" + Format tokens as HTML 4 ```` tags within a ``
`` tag, wrapped
+    in a ``
`` tag. The ``
``'s CSS class can be set by the `cssclass` + option. + + If the `linenos` option is set to ``"table"``, the ``
`` is
+    additionally wrapped inside a ```` which has one row and two
+    cells: one containing the line numbers and one containing the code.
+    Example:
+
+    .. sourcecode:: html
+
+        
+
+ + +
+
1
+            2
+
+
def foo(bar):
+              pass
+            
+
+ + (whitespace added to improve clarity). + + Wrapping can be disabled using the `nowrap` option. + + A list of lines can be specified using the `hl_lines` option to make these + lines highlighted (as of Pygments 0.11). + + With the `full` option, a complete HTML 4 document is output, including + the style definitions inside a `` + + +

%(title)s

+ +''' + +DOC_HEADER_EXTERNALCSS = '''\ + + + + + %(title)s + + + + +

%(title)s

+ +''' + +DOC_FOOTER = '''\ + + +''' + + +class HtmlFormatter(Formatter): + r""" + Format tokens as HTML 4 ```` tags within a ``
`` tag, wrapped
+    in a ``
`` tag. The ``
``'s CSS class can be set by the `cssclass` + option. + + If the `linenos` option is set to ``"table"``, the ``
`` is
+    additionally wrapped inside a ```` which has one row and two
+    cells: one containing the line numbers and one containing the code.
+    Example:
+
+    .. sourcecode:: html
+
+        
+
+ + +
+
1
+            2
+
+
def foo(bar):
+              pass
+            
+
+ + (whitespace added to improve clarity). + + Wrapping can be disabled using the `nowrap` option. + + A list of lines can be specified using the `hl_lines` option to make these + lines highlighted (as of Pygments 0.11). + + With the `full` option, a complete HTML 4 document is output, including + the style definitions inside a `` + +{%- endif %} +{% endblock %} + +{% block header %} +
+ +{% endblock %} + +{% block footer %} + +
{# closes "outerwrapper" div #} +{% endblock %} + +{% block sidebarrel %} +{% endblock %} + +{% block sidebarsourcelink %} +{% endblock %} diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/bodybg.png b/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/bodybg.png new file mode 100644 index 0000000000000000000000000000000000000000..46892b801ac1088cdb7091f230bcb0eec1bfbe85 GIT binary patch literal 51903 zcmV)#K##wPP)7IfB;EEK~#9!P2D?|o5__eV64U@ z=)r-V9t@6x9@fe+$e;&9V}Q|?MgfB!{4~dA~S*i z5pm)?_G9z=%U}Nd+wFe;efRtOulxJ`x5NGZ@3-G~znt&K-*?~t=Wma{J$^a=zWdMX z{r;Cf|9biD@XznRod5cV-wuC!{QmOSKm30E%b)-D_|NO#|MbiDx7+X6e|*cQ{dV|u z|9^kXPv7rO8 z_>@om+vEAE@A>w>{Q39mKfmWw^Ns)SfB*95U$%ccJ-_4A^Gc7uobwxhd;Gfp>mPpE z=6iqN{q6LZKmYsV^Y?du{ll;Oe|&p>=RTkFe}DXC`|BmY`>zkVkLNX?zW+~tCRgx( zfBb#-+wE_s-){N5U(UJue}2wS=Z^pN;g{|68_s|K)4#slkG~y$-~Ihh|M>L0wq5S- zpWpAtT*I%I@Bfo0@ch5S^E-~uzdil!^!$`ZuHkUjF&{ z`FYQ$_4hyh`{VN&Typ*YdHv;_Z~lGvk59jB^UR)i^!Dri`IZjPzkTW5p6~bn_rK4l z_q^uccloyb&99gLeEoI*d@H-(cmMBy^G2Wl?UZNGtG?z_e!b-H|M4yF>@R=5AOHQf z`R(@ax4w$oU;prYh=*LxU;pr*ulfJE6DU|NU?NB@gZY z{`j}Y^LDmbKF`N=$>09|l5cw6{51>Ye$NAczLfKGsXVXZ_m@1d=h8U;=k>X4x6e1FXge`5Pw zNcU`E-kO{-^)EKCg411)lAkpZnWmlMDaP*Z%19fByOT zx!bSz<6r)qb>B7ji~_&zyT1?r{%9pWciy+WrmXRQe9I+f5C8uDTx<92-`vdKPFXB@ z*w4?q|9;Ib`}?2%^5?();rTdkS&8|!-ww}y*fq?UUD+XpxBUe5RkW5E7N1@1wtw1)OD(sP~`O zEQx&MKfmWy=NaUEWcmJb{@0h>b?!J3B#|!5EWg`G{{HKw@8$XY@<#vur%hf-ZZKcc zRr#I(nbrCGdmd6=%k$-3bD7T<@Ht^AU;6yl2F?5Nxvma*jJf^XX7)_JGHWxh+fw=M z@Vv--Zt-s?`#j(L`+GkBw_5^tmRXj-_y5U-WoJBJ<1Vl6Z;w3K{M~bLee9liKK6wA ztor9|z2uSPdlS~P<9<2kQ=X6FxxAkT#>E3j9LoC7HRq0=FYuDxn19PQ$d1bHeny&G zf_WZxf4PENea3(arkxn!qy|6cQHc`gb0`PW2-MA0mUXH>W+UOXexHFx`bI`4Vz zS+|bE%y37JfPBAkE)qAw8e+F_HSY7*2T$B4M8W^SQrd6Xd(|yIBI= z@p%T%WA0yH5}BUS_?VbzyFZ`(bF**q$g>unyYZG?^9<&ng?wM0OV7!f^_W-me}Bx{ z%nnL`%1im}_WajtURr{$*Ymu*mxSoNvVVOL!m~rOhI2d5(6<){et*f0WcTHDC%olB zWQEI1@^EstW@RTJ{=O5^vf%#tJ>Q-e`p@sr&)?^J^5XNF5(M+u^3ZZl=Mm>Fb1vr5 zW*_B6{_Ww&%EHMp*1i1PZ+V$nRs63>E8)tkLNM3Os&_6!q1?QD#on|feOukBdp7G$6bj58wE&DAH7OBV4w*}wM)zUIWvyT~)oHpqWw zC+FbE&t-AV`+CWe${Wn9&0@}S%y%`N{+wl-`0|fW*{r#Pe}CNk{ZC$5)@2@hZaW#H zSDRck>nD#%`j&sspR&*Ly0b5{EAsNPmvfPM#d77GZOv)l6P|KG$^Nq|^S$}EEV?|1 zpDCi_CSf@Ln(xSC=nMFqZ_A$f$G60-Jle*l9zl6M4R5FC)j!;cqpg2xrjW!aA<~K1 zrE=@tHTY(iWvS#vCA{W-5=y&(AGw2ne$Ri;-zLIkS*i#U)}QzG)=K1&EtK${SNnXr z`z#L!TJrGJA4y;HobwvJ+8mlHi=?%AzNwxPwDXP6C~)i{aZUVFnI#*M^yWTPaQWms z-(&!J@wu-2M$^XT5s3oNjriL7=edwJ*}u8z=LMe?Vp6Jv*SwTu&H0twMoO~m+3eZ| z*LxG7W6rnk{RZJ@g7G;!KA|tGJrCp=@V;ebCU)d^QvfDzWD%(~@@kVnR(^f6~EoG#%1ma@OgO&@VU~QwaE|UBgyI$VUp?R&T@Fj;PWUFeDe)G zS0C933DTZMuAndKoZl5K?#E=;J+iJnP9Dial2GN|vZQ(_9+J2^X`jpcwOio1>$CHc zXFThG@4ezg*7t<>1ooWg&k%h|p`8elD@e|eMWZ_DQ#hyO&XP%%k%J~rFj;;6Hk&ES z$9B$9nYfcru_cnL^f13?e zWpt_Rvm5gp-SN-WnUg8Uiie}qkd#CvpMt2b;+XU;CtQMW7M#;6uP_fciy^n1;G1xm zE6px*{w2?D?;&UCJvR`RS**<-jtQU+qVDNa7C~M>7EBI@@Bfp) zn@@l4t^S?!Qf=`4f3iIDkXP2y3gehpl0!~OmgVlN79>B&5tEmb<(Qm5%i|fE zzh%c}C#PU@R6UQoZA!L8<>ofKWDohhyqPTOTwRu4kIZXwpVkB0)Hrz;c{1Iw`yQb$ zdC&QGN$Mu2P##&n$P3M$mKoEOCi<}nCi26?=AaMV<=~t48E6p zYpQw9u8=hS>qCpBlN??Bo|x0je4kdyET7Mcx!-Pi*b=EMpM=dUTRHIG9+p%dK@PNp z{p>RPr0LPQMeQyRJ8>WpseAjF<(Rw9CnvW^4AIWY_dScuufk{Y`v&N%Q#Y@qcXSow za_mgv^_BxpWn($!I7v#EV=?(gHda!^MB3bCGnsuBdj2&}H!Y-;vw0p_TuI5(vB^eD z1ZlK5w$and#u1pG&hO;V%+}47`jljI`MWG;+a;fvC$vfU&uO8}lC_=PsGFC3vdxP_ zcjLoON=as^B-|t!%qni@@cAf`J>&~>)+UxDz&{`2B`+eUX-k%?-|eOE6NcL(dxlr( zVE&Zdl!ut0-}CSC{L?M_CofN#IH&j_;Vpk^n!4-xd(IwA-mcr1g_Pe;Y1AtEm;gGJ z$aCqf#!R{p3BPLW+@}YdKWPJrKUpeSQmF{?x)RvES_P#AkQyfkMy{saw^O!I7Jr`k z^T{+yh?^oWk)+8PI6s_Ro z*?CCW{R#Ei+sQYwq_SI*D{Jj0Ksl3j2lIlGduPXI53UnY8I;}svvr!*M)qQkqCDQb ztn8>PLiKd=j62si_{g_>*hmle% zdn&tDwV!8|Z*MyI+C_0o!z%Zm2$ZLh=ORIKWK0gS7p`rM?&(JZ`+NRVvD}5#c5iz) zk8Dm?l7pq~qHR8up5FU=9#d9mU(Z?U=Ru_5 zl2?+|+f?Y3Fqy+4Kc5@S`jQQ|dOzpIJJS+XEe0(k}jh+OXti*&MHD?}JZYtqbYd3)>H=GyXM9hV!qBo*Q-kBGl zwnH9vE;IuQ4V*l>EH7=+?6Cx2eaD`}TUm3`%av5-8&d1$W)w^b@E&JAFRv`i!UQ8} zSsr;7T(XfanqzX6?tzoXp4TC1%d*Zh$lghBu657F3s6ic3iCR$kMg;R0y!F5Hh-$rekXOn5I=aR)O{mt^s_2o)!v5dPC1+pa@E!t2UnF%(vv6&iC4(jUXLuwJml{Uee=hoAzv;U$Tdm-i>uWqlw%$ z-^)9s+8te(h2%s!LWO2@JnEZb+w zc~fma&*{sISzqinhgV+ecXLydi@eQzayL^uxOuku*EIX{ z1hSdLveaOkG%8kmCm$tvv>EacxRrR>N3G+}d3mkWFPfRHVvi}N^6}|{b+mCwYLyFb zt^ShNkVlXsAulZ6qxN{+~oM|5jwfw0m=|=2M<`^saVFUoXd4o<{bi zGEyy`m!EH&3CD{@b|(nw3AQ@Pb50~`bE=!JLArAi#a^ZAuF-R8fA?D!a-Q5qb)4X3M3Tjjy_o=SN~PA-ot6zJ%;h!xJoA)a z37d%sZI!fpEfL9uJpXh|M92koR?vebAvFt4KQTKuGx{v0&g~Cv@LV!^%zn>lp8(x# z{Yx$%BB1mAtuA8g-*bX~ZaX`wn~0WItj=B42u&9gN*u{vVqINTae^b6dH=)imj( z?XC`mrvYzBc*zOdjPj6&qur6ljGWqf&f`l!HciVXcOrGv;VYWuOZUbOC?qeX0qQik zf{zKv`5fb#Tx)x2mwaNvHH1rAG;I(c5(JfV$^OA9QV{7#G}2tf16R^V@_^J)oyZjW zsn?{ndKx*rjLGvU*%;Z4Ej$l-3R$*2s_yCO|CqR+vp+LVD#+#15$slTDv`A{!7hs- zznMi1xsaEfpq;FyaFfmebIskiGg5=A^0sD<*co4+)iJ+qu%7ESq0F1;anjjs`Z@RG zCIKz~n8zfrr|Rtv*}8DKqiR||u5pfyX#_bNTJvO87SWoGC~;gOoP1pjhRq)E`% zm`;|Vd7D>}SJrODMZ2~6_|>aW#wJP46=a*FN1-=igp;z=&dYOXd#vBAh|9Mn^T+~D z4$^7HF>@ElqeP#)3LTalqS>J$L+)LFa%DkT%uaDL5!-4twnRM$jYi=c=>J% ztRqxlE;m89=}Z>VPKwx3%CNO*6|OoUeTH*Br^hW zgHF`@mpvq6=IT@(IcoBEn}q)kH`-U0gSRi$>0r_x9l`t>2&MI`o2<{DP?j7x>0MrO z6Q)bf&^$_+g5FmyH;*B!(+myj#hf|`sbo;s9uT59w|ma+WYTSJoQ$G!Te*FuWu^d- zcsUzY8wugL{-m%uI#yp#vYST?{+f{6*PV&`3F zmj$PPnJ$SGvOBN&cn(8lb!T!{OHZknXWH!tm8hF{5&m-r1>K(Kg`PC3jHlXD{Ww|u z&9RuL&@%i1L(rk|ag~DNcu|kf?Y_y)q_yEBar(if6=%0k(PdGjf&}NtfzjFjA&;pc z_p}0(J|Rr8WsyJk94wqOdp{4hXZ5?mWpO+=o$@qrw4H)VoVMqS`F(;f7+MYo!7@9= zwZpx789C5^Q4)s+WKuXsQrq+t+P>|i5PT&ygwc)SvCzsFrCAP#BKXWDZ-6I>QWC?o zRN81c<@{~vz9pFF0Brp+ZQS-dj|JGgw2W*zSa|EhQ)@|kH~Jl%!f6J%AG-;z3H9&= zsdfqjxn|>ZZ=ZEU8d+NkHtL+jp=_ari_9}sB5%459@(K;*~TIHHNemOZBNMygbA2c z9z|Y!UZbL>QQ(mVtU+#8Y|q_OUZc}~0T(5A_DmW_fK0`{wd%+Y$g712P+2F1!&lv~v>O^RdI1~?`g)@jSn=B0H0c7r?2pNk|4+VJX#NwCd>O~#!U zn(ND1oS5@-j3p&?*5)ZBNwt5IB5GICdS`5KAOFmVC!B^^v=K_$Dz_NEwXTQEU znTr3r7&bQb>+8#Jcp1QqZIr%G2knunTqCkAm6P^K_W42$p(*5dTNB*m_epk)IP+Mv zY;zk0fb9DnFAIy)#oAYu@G56W-VPp8MB`Q_W5ksQVfdU{Lx-Sc=}t#o0L|H*%)C9p ztBz(f{ZDd?AH$}cvhUO6J!EuLDoY#P(&&c&W(e8)*})kOIkIv`233F}K&=V?=K8iv zdyE0V&4dF~ex@1c0heC0(bf=M$!H|+xfD>+j$x164(0Qd7vMD4_@A#Erv@x<_Cj7A zc!MM?E77Ba#Lo*XWV2}Eq-qIXS#=&0RE7zxvX6Z~>M{%nPmxF1YC4ota@ldl$imTyTLaZT#FHId-0%aUYiaaI&alAdb5+UkUr;rA6rFSj6MbMD0yP^lS`kMrtJ2Be zE8;p!$e{TJl&omJ$Fx~Knja+l$DqioH5tWI5HD%JFT5ZVe<8lPw!9LR=nAu{0 zpIiCqq=*N&AjqJOobQ@bW?6|AkbdTQ1CIQbPt7T5gp=FqOm138Fo}8bxyMd8UksXa zm$|;|v=XP<&BzM{qs-s6WPD_?;!8C7Y{b$y_oB3>+FZVAKb1DJ14%t@i6#^kq5IKXssoLOmdwHRWu6pIw`KYa{Fm*oLI1F)80|AnNWgt z+YX7g;B*>qMK0~Nl>qNB5VAxIE4$gNSw?0oFv(3w8+}B=LTNrKW7lM0n3ES2|2%sM zc%rh;+vGB3ss@p%dJ9qbs6Cqyo)DOtG=FDuKM23QSr&X?VhIQ)?78VbW~^qgx)=8! zVIdE&?AA|NGKQki0^r(8tr-~YfFJTH3EcUa96?U(?6iEFfo}jHIf+~HoZtx!hgQX+ z*VorwP_-s+JMJ$noYFUonnA}pIkBe)|2~baLpjh7nw;ayB<Pj4FBWhb*#7l7vmkhn(YN(MAg-A?XLoQn*ivb?VIJn@F6FMeN zb)^}$PIfG;rS_2>FK21ddL8U^B_{HTumRa5$(ArDN<2H|^O}6#6rrznc!8vVZuX(uX zk7qs0Ef6kB$?D`WeJN;Iltm0$NmO11R!r&&H;|eg(0eojE&$I+ok=QD!BSu)K;|(5 zO`&KOt#nNzrBKXWPVp@7JjiA(TMWFUQBK`*Z!XEM+hW}h(&+@+na9}#^aa2&d$1?& zwf&8o{2&Wcd%Ma22N7uvrSf#KbhF?RZxQEB6q8hfb6_TBTjq#f<8QrHJy4urjO)CS zEF{>+EDJIbkP=xy`8oMRFoAnLBVsJc%2y9BuL)tgSod3RwLpz@o(wh8Z-;5ak}PO#ikLT6cxCrB89Tk&XG znMGZM(zW1`qY;xdG*^YzlB^()Ca*j@1#%9N1I92rUzfcD@uHq_5y~~XfR>~|Otb=P zp$bKLwXH-FxXn$?SacC-EmU`52ziOXwoWRlEZck@g%Zqz)(v56@1d*#$Ffa!2jlAtOZ0dq(WQv7|nEm+CP6tc4OxKk0x5VE*r+@*VG zUU5l!G_8^k#-k93AfV~U5u(8yTHM@K(VGuye&;|*qS+x=_yOOIhH|BY(Yq!#X{l9z zWBQ4W7M++Fm9?pjRZ)2g#Mc~}o|ZmgmT7Sr+ct+9RVa@XUA#vW(?#r5;eZ#dhmvjO zuqoKB5LuvpEFmfJU;nUKfKF#)=W1=TWK3Dm_pJ;7t(Uv71SU@FBfkL`yavNMi%omZ zzP#z(@QUU{JZOOcM`qEr=XUPHcn4$79ISw_@)32t6G2SG@G)R=CU{)h8 z^xhRS4=x&J>nI(XX=$b-Y zu5UAK$qQ`~O(f?!^ZhL;8EvXc)7+9psgy`%v=4dJ4K?{INo5c2-iXrUc+iH|EQ^xI zPWcUy$Wh);uPWRom({HKJ-a05M<4cu-WM=*5--(s^5>pG+a-V^+`zvS_j(2YN{`!l zL=vLfR9}I>lFk_T<~2&F$^*LCdqu_Wo9ujZ#^*s8$8_{jUZB2r%bcACQ(if}uUx(Q zBg>{!iXv;|-jp-iQNICQn z9JootHTGUbE_O)S63CXSdmwUsN2&*T7nP{|G8N0I+`|G%C7;T<4(QHhTyJfOtGMxcTRy<_CkByehH z^fkJiPF0NIl_?|!A)_IhnwRAofG(<2x&@yyWgOw0b{nU;^10V^#v)eY5vvrg!82j~ z^7C1&N?&?kGIB*V;);k`9cs6`KftXN0P4;_p+10ArgYh2P#Zl z>SVT9hR*|WG#5|BGMCq&)s`t#Y+gr&RxhitgT-Hrf<~^B*ac>lWdRwdX#&?jG_6$Q zqbEqHaT+9}I0i(ieX~gNOC447InO0~+uTo7Nv1C{(BW%$zlUM&(^GTYnN*gPbA?X? z3MsB?nzwoOHlnyY{mzf#U%45_A+f$;A|)d;iAnMf2!euZVv&tw>{MF)ZPOXrg9ItL zfwXazWO{hHeFSV_snzFAP|e?z{B#EJ#;B*@l$!AZOlyx+MEtKo4MVNRc2~94)8bYbIA&4}cfWzB+c(m@>g0u+r zSvXzFdx+n>SZruwHtibRR!6Q+Y^NbKnj-J2ncUmL=@*aGrPQ>naI!TC!3`obQ%Q|V z#uBthY)f{NHv zI1?za`#Wc+(KB*qG;h~12S8Ls-`VQ>fo3zT}Qh2*@Hdp<>OF18DO++W7C7)s))a^stgq2h3vl z1ML{SImcKr6=zx?6>0cHjsYiWP3&}8+d_J1!@x4-lZqxdV;cj+<{&8g_(c3t7GlWN zG2IIt1i4f@sdqEJF2olDx+JdoQ=WBI9&Uhb#HOA{fB`6t0Qw+ift68dGs0^$4_F_H z#AW)0zl{=sXoTWr@JIgl3s4K_=)8wKLVl+Mc{XkXrDjSck0`MiRbq4tzMZSsa zu?6f2k2(L>Y3T(;Zt|hi>Z>f`Hz$VtTt)heLMn6eYt!YsrW4+AC~fqIGKO~a<~}eh zQ}&rKBwGSNSIISsy)V$pAStU4lC83V@Jljgoetf*vu|t@48b9T2gY;~8yFv8z>|e8 zQ)Oo?ktTAH|DDPQ&)hs zWgJ21g;@hJD#T3VAG$t-DVKtGbCoOdSe_OM+{6eic}*g~^0vaRwnkE7ebF2-D5iyq zUWh{|@6%+%2hZ{O>wW`}ot>eDSs28JkrS&@P05$rq#v3;orv9tJSrI%d%nfpI~3u6 zi$*5EgDR!b1D;VK=SPRiuO{Ecyr0P{^k$ADys{I{yMLQ!FL;-pes%+4XrzuR95jf- z_Dt`v^$e^%-67Izc{q@_376)G1nLu@t04MCTuYjV(4EB~2xAHmdr~5I^i>dBF_oj% zozp(siYlx2Y&JxXwoAcZH)7F2N)V5z8kl+GSGuKSt%>a*jpsAbX)65q8QPj~KR}Gk zL$REz)5}0rPXyU?VtfHQ%!6>6W{vAi6-==sj>xv5>CA%`2*D;|C(4|Rbn`fuz(W^T zm3}mB6W}#Vz{v|YdFx|6mpsw2QhL`Ia|z8#sj0;;uzA=n2B0$I(KEWH9j(=*$qRsn zrvzk@do$An7E5>)Qu8YEP_@Bn@99hcqhx{5JVXDq$g9mi(c?NX{spIJt0A z>N%a&yiynJVGcb-9ei6pMAF7Qa8lRpBz%J+bRQ~tay3XVxtlzUbmSJ{oE|tXo-3eM zR=#uP>=N3uDAH`T&WJRvLT}kEk_}sTH`n0oN@K&mc1ZSmIiu6PBEcm-~cI+2}ij` z=R(_$C?5&59j6Br}5q*>f~C)62y5d?7WRl%CU-g4Bav}nmG zVg(zSl3`epVW}1yZI#)3lA+-Dkg0RnEF%T5b8JB4)4b&B3+(j@&{T_Q8W|}OF3+Wm zg1f`8uloa-3&{#-;UaZTxIsdBDfDNFYYwG+Tcw~b^vFy%yFk7{UGWVfote11`YIaj zu*p2lhIQFI!e|<}ZwcQ%7XTd3QpL2(3W+>W!5a;nBc<7Qmae0S3=%aB70&Q-CZhaa@qt>fC{DQ%Mwo z<}1{;DBw1>(p+x-P=Z=xXQBmFZxV8J4VH|2*_2my5i{#JNP4q*bC)nt#9~$p82VCQ zMR%d&`BKU^Ik#YZ+L|o-y$IM-X9QdMWPV|#dDy6+-V?}9U<=YCNm1bluL$5NGS#=4 z@u4l*wLn@ep(^!&Tn>1mAyqw|6Xm`vN04kX5tUW{?qAdDWTeoB&_k!cVzVdRH%%pK zU`y1p^-8tSE7x?=En7pH2Fr`MQ6~R`N_YV(ABKfl_5X7 zDWC2;)>u{!iGlS0oSfY=cclq2(nX(y4@|9_OKg6B(Cj1+ztHbI{5lREX;!_#Whp}v zmdm2KYzemKdzF!dTj__1Bp{`5&kEGu?@KYl zS9Q;lp|8GKIna&jSRQ~-XKZqX%QZdJ znK0LLB(x>8)mu+C-^pIv#~GVYF)u6Nfz%1-Yi?jF$kZW!yY_wpJhUx7M5mSY^0WKv z%op6l0~xK6s|8^0E>FljG+ld5Cv9f<9IrSjBJ|FWrP8MHqI=gF=#IF8A3&am$zDgg zSAv-BKwNPY9j=Kv?Pr$uMPj1b1W|LlvchO7_*o;n$ga*|mo4CCVa7%xCV1Ny^*3Ek z)NaGX2FB5yai%C`tj@f~_OzO;__PULcM{GZZx=90rRzhSfB=8w%0=(DUGa3gIl_N?iemloMNF1qU?) zo~>4xB94w1osO9sG!d0M0zqX)x=B?z0+DY(6?NL!8CW73)3t9fdgNSH9wsaq zqvq8%Ss7_`Lr(NW;Sl~NSuWI^FuXEuUt&lKfbnOZsf42BS7j%&~i>&kY*ypoykoRlPid$oJWK3obf}f z`Qr6tnK@EZ`f@N3q=)8RqDkxa7sqYh$I3j?YiWDuY{UfUh479urQ^v3tvc%8hG-gf zq7mFh=*b;>Gp!F^HmO{}x6p+ZD|Xp-E8>0B-NauB-CMm3`et6Mh|>PdJ?#b zA3=|ft1ceP$O0X{vz^R>!yWJtSw!cP(X#1x)*J8>5SDaRE+62S@T#|&&+fxHK98x(C219UWqe(9E=f*w9t+`$p{u13)#A&t|uq03mn4VQ zCSSYI>MYKnT~wr{R(xN5DZ+7hM6}8z-(Sinre7 z;KIDQ=ELn97Fz<)v@?F!@Z33dMS47mp@;W|hl*9Ar+z z*}%6-qYpil<@^ct$H>JoTb+(KjTr{G8gJwu7(kNBU4}UIZ2Ddt@s6pS_APf69zkH` zxpT8fS_cH`GgVlAkcg)I+07xiB5rWWDBSCd=d6|KkJ-vL6|;d0!zlaBxD~~aZ#a~# zJq^WL=Fl4(h+3O=h9?yw!7@%3*U`*8p;pK!mPM<{9{u|ac&L#rh$^5u)ow!5AYVY$ zlm@aW#-MGAq#g<78EOU-t!nq+yhgu*G(ozOM7fzCFmrNmywvh7sq&d+CF*Is3jcW; zYxLWB{LMD00MB8xK#qn-)lfUI$^t+igu#)<2O+;~Qxqd(Elrz_{F?Vj?U#K^C*oE zJ+iDxbnlWszmYS^t6gVQ@)Ag7Xrbz9ARdYaSBb9oix z4aMvdK>t(dbL*8qtXh_SRRj-=Zc=t8Bt;7%n(6^fZqT$99mal@Y|Z`);vl)U%I zBRe(8ALV0y+klcDyTSIgUk zU=FD)lAJI_L+N-xPnfKbf?pV6q|+MOpIJkYo>^H20ci;4g?7k&g70O9byAkmRv)2!*T z;4eVJCO65}X<1eYwE`_S58$p8dt_aUAviH<9mvSzCqy+52ZXz1j00b=Ug=rfP$ke! z0m(2Qq)xslF=-OD9b5-B(Z>{kdfjq*8hKH>EedW>=6W zPS=HoX^s|R(N#SD*l9o&9TdaO`FlK7VrQ!{{f|$ZoE63Q-TcE03SKl+z!1x`;WKq# zv~cq@6S35`=J800Rv2IwE|2;*FO?f8lCnmQ1}srkr&(f z<(2Cp(|00r0O;c)Qkz#v5jR~rd}9Z9p@5K?+(Y?HA82n&G`#>S37(M2fS#cH z1!q_JlhnuN1~9_;C}88^+Yzt8aT3Jld#?8Q84**2I;tD)UAkb<#99u$4x>_(=k zdGvPU@(v~@ZA_WRk|j{(--ir&WT}pXleq740v-jQ;)Wr4Qfp{Yx60o!M9fW><@`!^ zwzz`583G|#J_8_AC9&R6vFLne$<^wvYDlGG7nMj1gG~jW;Pq;A&(-HjYIO*nKd+m7 zOBQG~R(D3zG}zk^f0v*U;We~v>AUAluuQzEujF$IF~72=gCokZ=(!N7MioP*Z+sy~ z36oIzxYCj=hC=r5f7I0u>2Ac)?Ugp^N72RcDIj)RTVuh~IK=oA! zY?5=Y=GmUDL?Qz{peIO%QR!Q>cNN<&%l%Z11GD&u*Z#ffT{+ zwAI7~vSv|8vjZe$0zCF>1})e!rERtgQ0=TXq(|>-OC=oXB$0;63X~823>o$+h~6Lo zm(_#?Y)>hNvqS4YSRSOfQBm42Jq`%ko~aenNBa45Ic$>Wh!=Fw5LPvgK)E1@i$ADi z5pY`7i9X1svXfzjV79S1lkmX+X+W004Q05i(M`R<4A(nK_=iN4MAI6|7TRb&jucrQ z=b472YFsO#UUXjxrPbByWW^#m&VXbl%mPlS1BcF z8r~el)O(tKqA9@3PfF)3;}6E=j53}FPrJx8T!_x=rv7JaOglfx*jP$`&W=`O=Cj~( zTY;3wORBZdf zx`OWD@=zTPR#Wyiejmft`V1_)VB%zU6JfRV6s4)MHZ4)MkiL?;*5}{p|E`m%Yv!f= z)U$IdkAa>qK|+J!Qj=cvtn>hQ>o7dZD#qpoen6tg_u?ZGQd@Fy{=`2I8H^@Tc3y_X z(>;7gp{j}eR%nETsW`-&{GH?i8r+yzl+QH0{D3^idw1~da z?!~DXS&TioYP*{Q$uhyDw@5F@KxttmlhP4ybic)ERTN4KSl6%EOET1lBz#6vIEA3Q zv{c$;DrUlf3_w&%uSe0Ll~;P8*A3{EVJAwZl!@S4g<)Q6-F%(1`-0k7l+I570048z z9_QSuV_mg&mlbn8f*wmA%BjX?+R)Z6V^T-EHy3W+4G2za!}3Yu1$H?&#=WrwyoX1_SV8#Pyki|UKh9>%bCm^WJ9 zNhM7uy7W5Y(d*Ng2A4I11OiR-4AITN2(r*bqIxL%aYlQgiN3lYt?u4e2~XZ*)75k@ z=B^%Ec{m+}9IJK_ALKMY8B3}s_F4_$cXk`L5|aqDd-k&$Tc9dx63ikbnkBo< zS0M`tn1|N*DrD)3j{wEU^)IlmgAY=BlkpEnYwgN%WIyWo6JM}~3NCm69y1}N?#ZR& zr`aPZ1WqUIe{e}U>nV(2#1Ur?MvkcYXpbFC_6pB@TheBRtYZ&(W9yKtS;>QE zNXo6JZyv^&$ivqy)$H~G?-Wkkd2I1$oK$ww)_Iwus9xP~62qnWZRn#)n1EbT2k>H{Jw3SaK1OX~6iHF=ek!vr$J zqTfCOG9{>OrbT#Mmhi)0d##)wx}eoCbdO$Fgkn}StpgnLel#{#39(7dpk;-e$; z)VP!cB23rD;D}uaGzCG-46fAuR<+S_Smm zDp2(VtJ7B6c&3MjS3zb1+uE?kZ21n1NKNBJ5SmVWTPO*e?c{|Mi%CrArt64(!;=dO zs58FN4DNv9zEzd!TzW^fV`0n_1Q?Tf0qSLOb3HKH z?Y`sS6I32A@e52Ktv#7}URFDDH${!45d=zh!KN`OpAMg?N88+W{ooi(1Cbac9lolS zy-Ia+m#rYKZPBn`>p;fmQ6>Whg^z$!&`;zBkX>6scS)y7rI28q8qf#jjAl0qZS`eEvLBBPqK z`I82SW+ow$aTMFjS(V4O2`_O&C^o!@9^lP1IY;lta7G@XJ*xyaLE+NAnJXYP~y?&+|NRqamhPJ z6Fw#*we;HL?pmJViNI^q!Ml@P@|%WG{&O6DN#)jFPHEi7d1M#ia~aYNZ0ijkn59-H zeB}^1(z00d6u{$f9;yLWj6?1Xa*6=$vYuhgCDW=>>n9~Lp)GXWl36Z>z}z5fazPTuNUoGlX?20V|Q@S)N!2jR6Qb6 zDw2}40a)i%D7rH5CIR0u>SbLYka-z>4V%RuT$`mAw%VZg&V8t2Z6myFNL{4yw?W75 zeu`k_j3;L!M+g4GZd`ub;uVZx9;a3prY#kP9L+Pj(yn~E1vcCD`#R=d%~}9l^+x{k=M7jxpaQaLLdj?uw7Uqv&xrQj zXu+b;chf|u?J%7nB@?!K`u;3**FYOGd0^E)tiUi^Zc``%IEdAKc(nRyu`=<|A0 zV5y_ENptWRnUZABH|aJ)5Ic2E(0^#1?u*jfGKtX4D#rh$xl%pQaVOMw$6tW0aV?G~ zUB4oou3XJ>1xWJ#PD!>R0|2^i3cT{tVKyVsh)OO%$&u0zkR4(T#57%iHleG3kVUPP zMBZ2blwfSZWABE4RVaCW|AsSQ3z$2;X&$WJF+6{%V4tiUge_y0f|5ph+^8fsQwf;E z%&l(hPn2PR4qknth2p5Ak78$7r5azbs7qnT45p9xJkm}r5BXyY?;MC3uT+fwM();3 zfsM22`V3@h%>)PdL-Tu-M;O`9RZRdbl=Y6kpOc5#g5x41?KWgbJK1-N*rV9lMnI!JJX$ zI=dOt0qN!-U=)eX!I1^#DS1r|sJfJj!6?3%J39Lqt}eCZxN$ptCV?7~)}1kB&ilNc z{_P3Rl{&r`VP66|Q>!2wV{V1ssYn9;T1r2yu`5=t2OmBTH-OSbFQ!!mpj_|_eV3Fz~ao=m<#5^uZ)sMjn)B zrY-MWkE-v(*XVBIX`zF7D4TP)O$QH>M5!cJBaVbY5L2o;khH^+>`RZpL7#2h8RVf7 zF^is!cgJ6H+&AvD_;rp)lx&B~lcU49M)t3x4g*v&#>HyW*DHbZtHo1f;SOSTi8ofH zVa%aiF8O-N7%?YoD z!;S&QVnC6F9HFSUWdb)2LJt5qvqG-o`FA}4Iwz=T%_FWGGDsz1ytr6m4s@rvObGf~ zIjRK4>2!6m{Jlme(h&5Apk>gbE0i;baak ztqrHTYbG;QqCFf+1P+Iz%bJQiyRK=V(Sr*GKWI} zNy`3R{pV7iZgOgsc-E<2J@S)LXi>JEZqPOMUW*6BVITwa+^ZT=9s~MbYEIQ#tlW6&~%a)d)l;nMI zmbXy}Lvg4x?pI(6?U-_XZuDfRiBra{GgW(ELJ;ubf^C&;Ty(Jn&21G4crm`9LqPOF z8L6N&^nuO81<>=7=IKmm(WD{NJid0Z2pAZ6^oZ#XX<(b4lein?&3hj2(g!Basuo}N zi+X$&rz;PF0|_aa8514QPsc8z2t?XSMm-u^`R2rz=0it^L&rp4kZxFGV-9g*pbMrI zCzzw|XD7Q-jz9Gm`UFqt%`6pAjNmLT?hBgGsO$uNs2ydZkybSn}&kXbfVq z-<;k6&$I(o>IFgXpaL`MF_Bop%ULvZJ~<&dVmh0+=J64(PDJnml8`p>I{ozdDVpHp z61U3LgQ92Gf?WcDzzGWaT#v93(!pTw##vpPDlax$jnpQ}3HJc%V)PG6DBCZqXo$x2 z5At4;`cWFn$=*_s95frhV@0JkiDqiq`r}lwXfE|yNYGq1DvBg#i5Q*KbP)Huht&*=BNvoGIf9^l2R7x-)B zQJLqVW15d^60Ih0nSZ=>c57ZHMj3Y*1j+sptTcds3dnFESwInl_ry+i@i}!(6qBU# zV4+araDWv`WLYl9hRT$YlZ+9X&H^@(1ro~=&a+YtLHDi+psD|g5xFa4-K)cw5VCU9Ae${R+vkT=B;!mslm>~#MFN-aVS9`>;C54e0##la&aI4G?n9K8Q@4c# zm9Jmt=m1Yiy6P@iJfeftc5lmKj{-<~eb7>gwg4lX{uoB!_L0wJ<~f+B12h#=48(6^ zBDo3_1LzmEMuPJ-qCJ|;iXYuBM``p%jg9L*gVF}%QjhM#0Ju=l7G$c<`k8^m}TJ1Z^XYyh7?-5P)8!=YJ!qcRv6dKm9QT>)%309VtC%8fCaQ1ZFze4pPaP|e1CG=BsPq42*+D&nxB*azqrHu@wkhbmc7?X%w zHNv(7hB^a5FFHD=fW`HbahM0uI^`xrW(g39TN6s-TcWf*bx+fT-qYBxdf{2aRH6pP ziCmT|MaXnIGoJ&BqY*IF&=30QiAbHnpJ|_Hn8Ph)r(+_?<>fh}Tw33cLALGR=i!;4_SY4i65P5}ceq4>2gdku>RE;Kc@3i!0Z!PPntLCM<(lo+F}+GBiM77|Iu*u^Go9Jtt5lzX2nlSxxMKbb=g z{A0A+PQ2Zrj7ZBf0p^DWC7@pdP)FuZ%S?}ULq-`LV<3ljhU^9+cxW`NNI~T*b^o+5 zK}74I+s2VTIy(ldx%{^=Qf1-9+PR3C9k8VfE)ID=52Az<;<-a8f^fapD-+8@(5p7{TSmcw=7fvwDwhMV1M=!>6M!FTKxYpVAv6YmIP5Z ztT$XE)hvMm_Ng$bZU)X5i!W^!MN)?wJIV!#Gy^?(G1E73=NdMz=U7#ND|)->zcCRn zT`#5QWQAqR^1FbZ>YfjF@TOr}zF)ly`^w(%33wezYddGZ8LxoTC0@b*B~EsDd*b@R z0f}tZpoZ=S(P-fvS-p{q=z(#dcD|fN@+8sW(_n`H%C}`R@mS(&ngA~&OLq_|5=IzX zLK2v($+R?Ycf)K<8a2eJ%bFiK^-&CqMBO7a`VHlVs=O!Xtv(k=r?{~MSefAl9$#`$ zm3m${*hhE&3u0H{7hC3%@QLbQl}9&Ed2%WsvQONTsRv^e zQ%0%6>33x(_fslNu#LI*j^fXGS}kd>o|P&AlbUyuwpRCA$O~aHShqlLbt41XgC3TE*+A;k~{9L`QPo(6t@*d=-j@zo9-iK zYdVV-WQn8KHIzaPE#d9ViHk@C8C$bJ4V;oSzbjQo!|$L)qi}1jaRlDfm~kx_iX`sD z3uawaA^SSc30tB(%&?4gR`H$R0)Z!GxlmWhEl~Js7~hDQJYp)A=ThGAsqPW*4s5wh zB53azku3j!eEf_#_T}9jCs}+2K``IS2#2I;n8PMzDvc`;k1eCQS!NW5dcxO% z_%O-S2hG{M6vFMvWOxN=;23P@&a38AQz|tOf_O{MchwQK6n(@T3F?J(=u36q6`(gU z5ofxZsN)zy5s04yY+%&}_XMmQW61Q5ay%fp%;E-R0<$4F?r{<(XITKw+0*6XoB>Rj za*3Jy(WnP2o{Cq=9T#D>8R&r#JOn}Vh}B5OlLG`F@#M!cdN4iYhexUfbdp~YYN$EI zqNwN9azC%~f2$PjqN4P#1MoiTUQ#YipO9Fj@ydd{0#+;`t1JPsiv(Ked`;STckC!k zd3`J$b>L2BIxL*1j{=hsukE5axO1we1-v}yD;md{GJ>IXhOq^usTjshN$Wcb<-eNx zFBMfxf!1El4#GP;~pm!`8vjbGym544hx{QLOI%QeW zQ#zyLB@@7RHaHnSzTJOe{I?7s$x^Ynl1gfzOa)Z%t1QTbgD`$#4q`n|A6XR^5M94H zyT2~LM)gIvWGfwf3TV>_l-Um8-#T~Mb!K=Yajjds@RQ7C`b<0RAobN&*k>F`vfDgQ z(`w4$xnYBp@Q@ggFy}0*9QlDsadxPcZ_nfdNK566A|ONEQ{9j?Zp;i*gxBUfemZSr zv6u{GN0O7pB&6es-Cuqo%ETT)LldaD!x>E%gIkB)Wcsx8JAk^>W8@1qAT53vVT5xO zFD>2_dlm@5B+>ZM^4XG#RK%4i`$J-z#Os*ZoykUH5)1<3Ua5!C2Few{S91131*EDPxBjVGAyD_( z{V8g|D)MTVZ@4LZ&)R7-=X*!_|BF#mj=N$VPAj~&QvXWIp_t>nRx&V(=z}L!jo*vq zP$o4wr&sk+%3)}00F@D%`Dnb8G7YJom<=kYS5`LQSBgbi<6>P7ND}ot(x5Cz?F`xV zKyX*9OHqg(W01BaFi=PT^ST+u{GKFgah!gPS38BKCglvLi!NN+J4!dJ4kF%Ts*l(= zBMpF!AJT9aj^)dfE8%Md%(p4$mhS%Y{$}%*Z|-cO0}qljq?Vurs$6;^bmi49TZBmi z-#r{~?R+BYC5|F}!Zuq!s^_I(ZQl+wwwT_R`i$>6^yKx(0LW(1{Uv^my z7-p2@At{nV7cEXJ^qobO2TPijM>tuBTwT6zK_duV>gO37a~FlPV~Sx+osI)2byW(c zN?2lxgS$BrfFiA31KepzQS8bi<~0oHRiz)3i=B!-FN#}ud#X2jf)&?odij&F#0`au ztDJ$cH$eN3H**p*jm5}k&)1_Ph5`MUMj@H zSHT0KMPUdML1!OQx?&xXUq8ar?bCngWpHnNbz7%EaK{ z3R**)hKyDuCE6_%QapohKngs8a}z|^Qk>D+Eyen?$sO&iu_n}C+a<_A*zo^VFYwpM ztub8i8u5@IVc>z?LWAY2&m*HuzfdEEyN^L`iZfo^DCK%-sT}MJvTf|u3&Xhc888mc zvhWaD+vm|$=BhG|h}HIay~BHR(JQ=k|&n+sWlXPx&h8}%1SLzFDv<+>f|wEpAU1><;?Q? zZi9~lvD$w2KBunrUsc=NGCdaL*p#uFWsz>$EY+dvGbYb3BN$blzvK_{hk*kEX~LX- zB0&avH`ptj{+LM>LUC~Z={tIPG6kpu28?oL8X73xC}_})^aRBrgIDh85Q=gEw2@pX zA=ts&LP%CJqA#zkL1c{NHAH05H;i@K%4R>+*qJ8-^W>Fgp=(?hnF;muo|g^}{L>jo z*Oa&}g_TYKZ~V%k4whm9H^JfnZgp3=n4`!ta@F9dmhz^uV@F@PTENB#s$;6V9r}D4 zMRmaAC^N zi|QQWU`R4L{#W5p*_GvuSS>%uLd!LqFc_Ii)hrq!%jOEGR)Qs)IU;e$p%8;~NKsOY zSv-{kus3BiRMuyJOoDGBsnH_yePl52Y5AyQQVJ@OL2k;){IImbypKGi#Era0UM~3^ zoQq!7U6Y(1qkgOcy6~EVg_#Amk?*d@KK#|w^45l!5st|a8Z#s_C%a_lEd{+&wok++ z^4nQ|7`fvw9xBsUuSXURtW^N|9uOQDHLn6t9WqG?S_7)fe8-W*-6F6fJ!hXxv*x}U zQO;P}S2h3VWPRTke{1L_#`cP(BCCg;{S7Q=gll#i#96 zHgpB4xqY#s8oh!$r6fyln96N>w=H}yMFD~>>-T~Ob}e3R#{~RNwl8(E@(u?I?~7N!35@Fpu~{61Ji#1KZLIB#_Ok`^$-kU8fI}wG zN|=^{?Z1H=GmO`L%L+r^q#i78z{ByQXLdjr3{S{-g=hg&iGVWKfTsd2m3YdI=c^I& zi7q@Hj5cydRt^>x0h)j%Bg@g(J5%1I&&BL2RSZG-A9nKHTZHN%dP)nwC_FnI9WO)% zcX$Lv;5?>fdt`V?1JNDvNd#ckPf^8mvNFLu?KUJ2HdZ2=NF&S8w$4&sw$L+?eXyKk zG?OTxpO~vcm`|gp4$pT6m07T>AFC}~U|x$tIaK20X0>B5$P6kMP${c(2^T`!)Kc}E zOPtc9hyXqV3D;V-wJUj3xgt^$F36HIE;Me_hAW1W)B zV-0+nLXxM2;vpW7q{;4C+Nfq%ZP$gbaIs2coJ1s={lKaV;+AV^jJRvU7y@e$gOQZI z+*-->KiLXPnbtNhq%6fSuzAMWrXD(xA~5$KvAC_TcTX>~)WnhEm^)vf$tJQ^mwm54 zQ)cItkqj2LC6JAkjZJzh%W;DgM%<;OtE*dR>2)3G)jn?y%T{R*la0}~3JqikYRQ1|suF@IEx(KIH3r@=rCsBpIHyS*8cmbV^=?Y#q zDod35nIG8k$>m$(?JZ!`T9opVJIL--<6O6IrPJfmR!L5V)11fHQcrvAu^{z8v>gVG zAj1ywwp2u-!&jYmydApY1$o}>98|e32eezOlD*`%ro^+N{+QyS5G+T|)f` zm3+Q;fk!xwt5e$UsC@!q8@tiG(fBD<%piWR%a)shA$V%5}p*Y zGip4k&;4&Ne0I^ZnKv4*&>gI%?hYveuV!`S_jlF?(t2}ZlAe#t(cr`JbSnL-GBwgxetV`9o2zVdLGopX^_M9;7Pkne7w|LDnBce9oDK zEF$TvebS~*$FhKv)v`En>==vcv+uww!lEm<`Hk*%XZa&luL)C#$Jc_ods_oK-;K6r zLGC#HjW2hyvy+;({2Eehyva{X#h1A?!EBYvQUI>Q$9R$Cu)(FyLMpAkhS-fXX9aJb zNAvNft8Mq5VFTJ8J{#r~T2~<#z}ianZ9#Kzt7<28LkwTD#l)e3>J10*XUdstwXw5x zWMrlzG!Yo;Zm{h0uopgdS)`Az$K6ZIDUR1u4$;nOicwf-;!QwA%b;V^_GO720N45l z1{h1EA>Ak}L}oP&r8kmMteu+yU-c-OkGI0Wu1QMAHnjp!`!%olQI%gUkS4Py2_Gae zDLhDMoW1NV!=~v+9F&=A11g|-m`%n$V-e&}CX`A>)k_P-9sKTM1QpJ4Ag@K`AJ1RM zb1gljFk`X4g{_VVd@&(EDK3Z`!JH{%_dE|ez4_kdd!gqhSKzVqbMfmHY?@had0kNi zXKSpRo$yLfej(^IIC<66)m>^I9c$i=dUVZAuX9NmjC5qNGf^aws&R_(>Sa*9&-b=z zQpx0LeB5ihvZY_R*vm`VL!$@Kk(S;M#jNAX03ef+9#xZTJi=3TEPE%S%0PAsVa)KOQ}yuwHb%80uP78V(c8sdCj zD26IDU4c-kspY^xOi9V@wKrQjFG~utw{ zm|PWV{5YcC9CCzZ5$8$eB?U8vF(y~}D|}h#AZq~2NXn@I@f1kj1muZ^N4SgnD9tc# z1;*ONF`BP_Tb;$FdFH)kIc&&@;E6DCgeL7Mw%=r5)iZjsrSwSO)TgT0uVegwW(I;^@9$p^lKMa~!z|6`OZAhFO9e z1-nhlcC2Tr*lRp4sz5+wd(l1a4E2{xhSy$KqDK5^n+sq z9fFP3$&q)?nSpJkzm}jqjM6=?tyNXx&&ZXte87#ILS2>bGj+Qz^?uc{8l2K7HiDqp z(duDo@l*0aSalK-TF7Zk7h4A$3NE3Zjt;j&UOC9>sN&|A3M^>3oP!>F6_84VXSJB` ztrg@loj6eS4)}`=`y$Z*(~dsUXC#np1F$T~opg)~5V;0BxzYCa1Il`B_v6UqrSP?P z+=0Y{++h#M4u+?-b{)On_tkz+6kS^grvXM-J3j|01?7(8j_XZtJZ$g*v})&mR(-y5 zjLaj6x)f(dLmf(u>;!wrd>`;D zsUWf?!Y$a%RX%(TmxZX*~hS1{8<1Fke#3_lpL5HHMC7$IVtJ3abHnamnbdT!x|CO z3nH|j#k({|Nxz_6<#ppJTS)oW;_F&3+m}DZJ(ybtJk-)8N##LCZtE^-acj-4#N;ki( zKjTr+s>9of?2d;jdfNTC(agjLN-m0L*5c=Zom*naBQc`q){i+DpcUQygix<6>$1At z)x>}UU{B9jO2T3iN2Waw(ri1s0wIO2(2{u`;^S$NxCq)V-9fk@FbG2vDWc;BpcBA? z{bDoohejH_+kU?%?M z`!|cP3*5YPt=jGw3->&n3a3BlhMIMmd1ZChTCI(nCXlBkYQ7Y$Er4Xrqz%R@^#I9> zB7#R>@#pOQ2H|$uPk>vMNPR#WW zN<_f5u}BjlYifM1cHohd#ZN{(zmCOtohHZkaq-GZJRu>ap*zNFpWG-Q_-fA@zOa!j zB=Tgw1qmbd^l)?4AJP(`NY+yxVh}8De>wyB5!MZ@fBoyfe^n&#MzC@1aoCAg!fDcs}xcvgp}r> zG<9m4EJ%I;?rAwD=Qq}-U%Zrv9901P)Dehr6w7(o;M-^QrD`?!45wWz42PhW;vXD9Z{4R)U8N*lMRXSLg z-UAUQpl=ectm2HPupT9Ri(iXMvc^;89$v?K^)uj@5g30YR(Gm|)tDilD^)`QNp9g! z+Cbt@mWp{nHj|dKSF500T7-pnJs_frkvcBbVxXGd&yVCiJ3W|1@-nF_+Eu6+Js&p2 z{%n9vR*bW!Ve^H&>rZe27`Ez^_=1;A>4HchPLNKy{Wc*tQ>}}K(vJ0&gRZ#&892;4 zKbNq%)I%VDma-tz>dM1Mcx}&4g+~u{z_w?^mZ%OIMWt96>T z7vs1@B+MPtk;S=%-?1>I&dS47Cu-~wx7s3d6e@pVN^eS`!7!Fb%9VHb~?eTSLNvCKTxz(TK#-f#m5fRFPy1tv*%T)%S^Jx?f&$5E{^uOCrezz&} zBd00mWTqKx=nAks4BP2KbXqdDL>_H6{XeF6u!svfZX&xB{$P4d@X6S=wt4_~C9a`` zr2zDN349r%6RxAVtW;(0v9MdeUN%r^tsog69O?6SlJ`P-h|G&Ls~x#B04A6NiBx3g zWo?kUVtm7EBdO*DTr_dl+Rf4%gxbI_>J|Eh!-wn@NFwJslrRl2a3}s{+N6XaDE2Oz zo2)tMX3>*HZTH`A;uE z?{179I!Ba6fUY%iT(zE6F*+30_-G%WEF=X4DV^s+5_@@;P$iV-l#ae9db!jL@}_AS zU}tXV{m&qyXA60#shGdh#$8hDq|p(m5H!5_@d~&Qg<@`yKbhEJ)F)rYuCZwFZPIX| z?z4h)7uXAULrzJfjkJqg6)87Y1&FzX_D zLo}j%7^Ak@{y?XwA-zy>$p_VtWvGTIhV=vaqZO7{&GvRp;_?ug zIzU3#Vel&%9A?$3ZG&~#D7($!h0T*}X`m&aafi`HXfhXm`w)wVUU#c$Rztm1wLvkF1 zto}2vtGxr0-?ZmV2P%PEiC4Tzc`A8%ba6B@iJGUFLi{f4sJK6v{MPC(3=%>#q1QJy z&Q;FM^g+E1BTPzF?~Qp2iK;4V?U+~L+c3HE0wz7WdhF(DS%ht%JV-?nwS+sQbKEU) zfhwjDrvE3=WL)#J-OFRWT&W+rYFR$ejkT0%8JVb}jD+UvgyTgc8w^bSW_m;FnkN_( zwK+*!L&qevs*`M9n5^G!8&HSRGU`lKg^gQwclBtyjtw`)eB?oHAbmY5cx>1gLJjiP zVqg(RVGsnWuFyp^uFE+XM~BG8B{$gFG{8Q+rEqV!Wnf9IEaAGu}?TU1Vc zI=-cO2AObZjoZIVdV}WxRkI4?eUIX6pcs#zQoO^x%0PESWlcu)^~^(HUD^$*Ona`8tMf zBf74G=25e01g9W+ZPt-JC?2>H0xgg_suP(4xHkBF`9jAvCeNp!v9Xv3^=h(R(YcY$ z-xWH3rWwL{jQN~nwhgO26OJr~rtA-*UtV&K=VUd7n{)<9oO4-qYz%>gSDoli1&?E6 z`qAuNJ#ApK%DFL!?uXXpu7gipL3ngj>z;H?0dWR|_+iIg*P2wswXLxOrKSp;eKb-J zMbYF+J3ZX59wR7vA!&!zqPA>;Wt#5bXQVH3iY9eL!YXfmDMv5^K67uLi~5H5g*YvFFoYKNY3b9 z+0&q|_*QvFo$DTTSgOCe=hX;Ltv|W4pe*LR!40(!c7!zXD@*!;00FF!SFr-4(|%ZL zUq@rJihQ}%F>>Ru@hUJs-NqJkC|Q*Hg<*6@baYJM8N+-4Qd=`LsFxO17q(6_@GUG#LW&;`I8lJb$tbF> z1|OV_#@dj0Z0&HMvs2kHaZ%UTlkB2ewE}--eBX)t3F@zYV?__<`Y5wwVHczHW|Wec|&7u%UvOu}=2!{%GGjmT- z$k^TZ0_P_gCSWDUi-a$oC*u&RVJzYj1#0zvW8~I)x}F7C3nD;eO{bTJ>2x8kyt_>Hpo(dWs86W%pq!XcVhnpm z8JZa?Lp|5M_zTY-I>#g;F(WD){Za3sAU2l0z!{8p$B8g6UImuXFYDILlgwk4+qE@Bdb=!Yfoz zHT&<*SUGh(9PM9#L^!vVlEAWePjAUT zEaj?>Op>m>7^NUnc^SZrxcbvUdz9;YL-_C#E84PC?J|l4SVL+7$TlQNm5|RiA(v6K ziM8){yeuqE7whnV7Dx=4YW{T9anDl0g(7#swOfavW$6yAE6piv%DR1VK6xFdp-xpx zdSAn)3oFg(4t_B8)998)d-kP_edC3k;gBP%TJ3jw204m=TG@3Xijkh-bG9ZNpz<@# zsGm}K0Z{VH*IB>fxppTt(>Kj0^-3Z^nA4tc6mZMPF_OJNl+oNOI~jDG`nO?;;tZOY zl9&#-2gjDJud%{xzPa^uBa&Hpn>rsCFHnjI4@Xk~RtP-2jnL~4d6c85vb0JvmQ{qZ zW-m>(k3FYxm4e$VNHsAX|1bQLu>!_b{Hv}(%`P6&#jp&Fcslcc5R4^7n|;o33%#AI zTJkUx1U54ayf6X8A<$Xk5NZg>M{ph8)g=OxCpk_?1;gKpK*{|4 z)jkGaUSN-`zY#{*n$F<|fOe`T}1v^Q)_(6S55M zOjb;EsHu^@lGk;T`AVzNz->wUpiL_t)DgiU<9g?MW?yqfIwHC;6+(V$=iIx{?@h>&XTJmH0>Kw}d#_k&@M z+#9^RGS538i8N7RdH^Eoukk^TGy4b+m#lhsz>&T{JN@s>BU$5&2H0yA4B8$uhT*Hq z#hg@qv-J-QHPjjfku}fJR;L`!tu%+&a{Z8&X?)!ScP3DlF5uWs#kOtRsMt=v*iI@{ zv2A^^ZQHhO+m%$3y6Nej>6v@i+~084S$mzc_kN!rZD2-q>qkHw4dy6|)qy;ts2hg~ zHFVn?MXz5eu+bWPtFIXyN%arqy6|Uhy^S+4yGM6h>@Yf?+!MJzdvgj8lLvEA%%(I4 z3@=UzP+23s))&wRJ?p%#E%zls3hM=rH3^)U3@b@xcAKGtkz$rCVK+uO;VNvp2)8a1 z`&KH0;Cd)#N>bAvQ#9*B|HYOJAF%ywpe%ej!YvPmNF1GkuhZFa@=>Y@dtxospjM`) z8Spq#2{(pQhZ7@B8E(UB@&Uy(!Ig0h-zP~f?)Z+&=;RUpQV1+yk_{sB$j8h#w@#s@ z(S*X%b%Oe{mE_?}`l9BQgeMT2$9RpB$5-feL|}pqnn)Xj1^WQiHqOERC-g9iOfnV8 zb-uPCAW^eSp*GBn9Ggf9lN>fVP?#!*4OE}#O;fbck^&%F2!e)A2C^;%adEt-bTjU( zW{mgO(zPHyK9ND+7Mc!%d*l6x9_{=aaV^_woz~ec0~uW4N{ZDGVoUw&G0%DXw;*ST zPP(_>nc#HF4o)f2z|_+29nPrSi!_-{eVU;m!7Opg41jF5W@2@0l3sydUZC66~TQF^dsiv=b4OMKNkt9(xVpDCWX zhPp&{3tdtNkyiF%O&KT=8RimaG@{bLxM-*?YQi(6%Nf3*qh$C)4AlDX5t(VGEG1n9 zMhjuk7tI8;xrW?X!@BWuKkO)a`Cw{vq}6teT(yQ*F5aY`x0V6f|VI= z7zeFsi0DR1F@&n@AtgZ}(D7r}jrd!4cnE6Um;}ugZL5E&BMLD2r|@s`^LmO7VA~mFzQK^<8+m-abi+8~g~pICEreIn|RtA4gs#0WwAA+zG=% zS#n31Al*=bQ_nz}(CO;^Wzpqw2v#z?!jFW6ySw{?E5k?yZ;QNo6Ndwi4a&g!*3k_M8LA}8J=`tN$fof47k|bICnOL=RQ0= zSy7>#5J&guV}n$ z@wK!~t?042@jJ@t=Ub@4r$3bYhnw!kcc>olnqfwLUcS{cooK5oQjG$_BQuVVkzk9) z>J_T=OV7501Y(s*3~F1Y9_D!IX(Kh2R@Fo*c_Jxe}q7c z8R%70L{jeAb%prQSTiJB^*9|kN_}g@pA?uaHkA|(0@PfvdFjVwl(b89fH%FTatML- zle3v2OdM$WDBDfo!MfH zj01m(E4T7(g(@5yEI_K7)avOvd}{^~Rd7)`EcOQVK~CIB z02S%4$%Slt=ZgL2e!$SoPi~nqZ#%n@Xj_|mYy>uT+vk4nSDys&BXy%8`af&&k$h`? zp5McX&(2KO&Y&LSyOe&@MeNm6XGqZLFG%kpO?v42kiSLvw*ZAwT~&EW*?&Tvxq@9) z`fQ9j`k(|e@gr>Pw2mRyGdHzVAULALFDpgp;6wnkY4{X6vQHok5S_euO@kce9hVGFnq78{fzIjPhs!dQfA>1GP9Sq_<5AYe$S0D{AA| zt+6~I{%Z2cC?!YFBFOv$6R98wN;8Aw|E*HyQR<>sJQwYML-y=ihAf&a3isAMzcnsr zmGRy;%NZH6jb(pbe#$Y;(enxfZAu}!-LjRBt?6`d6P?V z%*+m&aGnIr-+7G%jQ0x0F3p@3`~5c7W?*0J;Lhr*+&}D)D1xa>@IYIz;C)e%pdtF?4ucL-pkBU#`yUCLj(ZBJ$%%5}QK5|N*&#M2!4WYVk10Z{hAh$j1GqL+v zKr+NKC9s>7-D9ReK*fS}L%#Rf4(1hQCFBu@&TH-FftV*2`XmZh5J?fpl}l=DJ$he7 zkdC#am6RX49xg6Oq;HXc9{$4%AyZX{_Mwucw*X^vJIUCEzwFB*=bCCQD<|fVGH2H1 zym24YpO(~Ul(IJPT{#6Ms-nI}LdwQ3qBwW347$e<{|6Pq>iqi;fUvDL>>6lt6Sln= z4t`(KK1lSy>q3qaZu(mOC52psaVmCr$Xk4$c2U9Eob;kBm`HTNR&+db40=byxrLr$ zB3LOd*QZ_b1W(E15BU^*E$v^*x=X6)cFvI zk6c+F+ah+1g)Eq=y)@kJbANQte~l6B{@o#&`$H4HL^P0EqTih;Yb?FCA{JAqkIVU^GqIihksha@oBveQClAJhU*(? zXk$h_p}p?Ay{Kgw!^^mgbq#`4VfU#{7Uc^^|Sm8 zm?8-+89Mj8gX2%x7?-Murzuk$nz|v?i#Da}vFk z6;+pPC->+VXPAD)aLPAZv;lvAj!>^Y$lRcDhBcUGrRo|?YX)y*0@iwj74LZx_%0mOj5tn1}0RI)kgAIU&c zd&cGRk@OTYcOfU^AF)%0x?2ePG(V85m zRN+a!pWGRZ1FJ@#JQUF#yz^Z%gqv*U*xiTlFRD&c@H&`3kWj1l&)7-}Trn$YM!VNMh9LyPa-_&DG48M%&7l5mn-FV$LuNWLMBXEHDqEqW<} z{ZIw~k}Z5@aEr>c;LCnVk#qgQ2>k~g+-L?6ko+Rzim8Q@%t_Wce8j2OywP{h^3i{v z^UGaTb^mUH#x{QGA;%l?IEXmD(bHyoK4WN;u*Gk+6Y5e+lwg~KrivyRb8bw1&1ZFi`t$|CfEM}>PkotD|S;X{4BW6fLs#yof}pF;&t#(3DbVX) zTM?3Ep4X5cP+^=SJ2W4si;7T>++}b%mCs3uF#0$9iOMBz${OW_1T(OH zrm-|PUe}xH?sPn37$h8i=HkTF-rpeL+4Qc_r;wxhFYQMGd{Lbkx8o?@0Z*q#DF#f;(UqK9=1?EomUycipeu*v3V>(Ql!*I5qcY z)K)G0PAbXr3^-_|LHoEIn zj^d!bIAL;Bq(Bc)h{oaLTQt4qo_#mq7bC}1PjYL$m|rgU@W+g>x~2;E&8J;<*RHb|w2kje#K{8x2~-a9%=hKK=@R*4SkdicnG7Q5TRfZ8#oOL6Dw#EKFip-CAh#h-uZwNhfnZ{*; z!ZJQkLL(uAz$y?wWl?Fp)s{%g=NRu>-XEp0NN;JTO^*uIUphf9-n*@y)qXnKuhR}b zN_;Or(y)?hWsfd8u;9^43)P%eK}evsL>>ZVg7yU5!7VeUgJ8}1I0+1kS|PV+IJ)~^ z%j!|2Jxd(Y(u!UK19RNQA-Z_Aq3=bPcUTql)f5#)DRhOTn;&WzIFGWxVC*xXPV!Tg z=0#}eBD?f-CiNksx_@Y}TogR1ph%^9+;$Eh2url&<6H(P;=?9j6B$6my~MhFpu*@(<1)M7t$ zif{F<`tgN$WV38B?&Q{{(Fup68T2g0GfxlPpiT2TY3dQW@cJXjgW*9?RCd@c{e^*x zQ{5N1Iec_f>NHY;#nbG(WNRyo_-4>6Kxcm|+&Wp%$I5(T4x0E=e$Qc%-oR`~90iyd zbn3jV$|7rI$FQAMNRccN$F|7L=`z~-OVrAIJxUt_c!W8T-m6#MRefc`qr3EBzG-Q3DR35N0N!m_yg z-L~AwsU;SK)cE7FUX&DB?N$=}MEWcfqpJ{M(AjVG#@vTJZ0S>I^70vmM$I$I2(+_- z$Y08ty^yjFBtaE9^d-X^RNB_a-JZyP#MYSe|w$ zImzq`FBbn?F+^myely$=2NRJLYI`aQ&~AIaV{5g@w8FfKu% z>;v3bYoPacVm^Nc=~!|J3a=i($5rCd@Wzmm zw8so~T3;Hu4=UWue_8TMg=esSFTnhqkkj!F|ywB zv3d9tSRTaxF52^Od%^8ls4Y?PFTDeIuz!>PlCmyRDsC=Hxem0YDE%5bvO`?J@wZP6 ztBPwO5oLm3QojJ5(rXGPnUDGlJ^_Dn4v;6fZ?UJ{7A7jxCoW)kYyiO-k`>a{<#22JajKxai(STR_T$xL5p)dYTvm%ofHx@XRodNIEV z{tvTbgn34}`+b{XPH#ujrLnod!Dv!4RUN#`N4<{20zaz1iCrvw=IiaAbl6={WH zyFDcmJs?5_?Y~hSz|KZl;cUeICMyQUSU!n8Y{^EaAS1Y_WN(okp*v*4-2cKlEb{+> zbrg{(I@LW4zqfdF0I7Hlge{UO=2|@Y!^F;^LSe84UF1|&@Pf7G7+1;^h)`&>!K`f; zm3qVL0esGAt_$S0Os(Lywb5#>cD@aooEley7HCCVIL=GcC=sL}p;1W6vZ9|ZK$1=td|sQ5Ph z@l)!V<O>&(K0^1TJ6}ro%h|oK*)8;r6Ld=7{+%-cfAIQT_C-%fDm(q3hh`U42r3fWL=mDN@T_KtB6=OpzJ(C?#SA1R;ZlB%jL`_g(NU-Rwzoh zRr1Hm%|Dh2wK+3$xafacD-p7_w>HzSCFKNlJe$6r6}|?Z2RT-)fQGbzk-YeX?9KdaK_OW#$@0_g^goXGS;XQr=eE<00Gv| z8VA5m$>W6~>SOdcEXFW{sG+~wx_88-6O^ed(awasw|!ayEa;FOB#mHzkMBK=h%dCX ziIMd*GkOE=<(9!CaL5XN+pgeBFqeRz)tsV2)|DwnO^{LsmTs69vy8O!DsRDNlu@i$Lr(Lqw5qc_aU=qJp?cKa}f zb~xdZPf5(;VSCI#R+c|lW<_ttQsS{Wv~X$R1k-KZ(-Z*1r5`^*y3n4scAxid(O3vm zuk;hpv#8*B0vP2AWQDq0Z3oc0I!GdTV6H2E%9pj%1K}Tz-(_}sYa3dAD-QAQ#X+*u zL~vk#<;L%#+2Q|Gji@d&>en67a#3dwx!`Cu95qtqx{dU=P55d38PFRrQdwNHfA@3m zwV^<+a{D{YZ=5}#gjnd9g^8NF+8brD+KMZ2xplOt>=#Ah$az~ee=3Fy;PDmxKs|7p zT%Nj`8qEZ)9>#kORs7o%|KF(&y?tVl*XZ_4kx9>=why3WVV`hGw)OIeRDVWS3lkC+ zl7f*69c!4f8#IcA%;`3KvUkj|0X;Y^CYTS1q4iBAd0G?r-ehLlN^dx-IK#d)7Op$< z|F${|E<$wKvdjM`)`7N1AHiaI@&5ISwkXAsZ;VJf#{Gbshd7f(J2L-u`jWkRzi(u! z#X2Focrj-aAf(YH*%KVJW19$fi!TX(Xz8hj*aTid5ArC2jUSozDLl%w;aUK^pr;E~ zg${!fkwgLf-quDnDx|2h67H(@S&0Ozd`wG8aCc`)8lRsr=vFsd4=#AeA3=Ka9U|#U zTN#^c+l(ULa(^1VpE}*9@cmVwJ-J~fe3s+#C(unWP{xsa+$4b6Ph}Zg8mXTA-%f{L zIOBgh9ZxF%-RZFFyNV!h$6c}ptZbW?+~Se_2KT~Qmso&aqv-~H$s;i?u#Ak0(c-PH zypns{aQ<>S`cGC5jZYSdtp|xSIaJn@vrE8_K$28ynE@HkK5pDLs+_~Fb%9O3YxK~j3$rhVTfFhk1^d-sl1iaw0Y!CzU#^I|97TC zEvx}$qcCi74%_SqM;6TH{w3K|b$paV9ROjZCW+r4w=Q0nqBGNJ*Wj(gU-}uz@3g!{ zyMGm0Z1LeM7cM(3eA(r#UIIuIeJ@(`Wf1^e@RwSOR3zy<8~uao@J9Xz)q$~)0v`5i z{TvDn1zfJ)X}P}kww=e7Keh>jK(nHZH!DHBB=A5PP^G;0KK`XUX1NcGSV+U?bd(hw zJVprHrYP4!>y3Y4_I4h@@m7S(nc#rzn08*_GYhc%ehV_*Uqf9+25^C+jpB;y)b^gW z&iBm~)%}#`X#VK$AYTit^Uitp<)!@w{7dW5Qto`=Cg%NLv<^9cJgViU0<2G*s$wAzNx!{* z;P-!P9hJt8Id{QY2meFsz)Dx{3cy`Fd9`CjV)2BWRzhzHcN`n2ZgwMTUM8;;xXk3? zgdOnKE{499Wum@9uTHTeAqa1)CiGFiL54Wy%_vh*wlLrb!K+)_kmeQ{uYQFq5rqp!9P97E9QVm_b;=9^~>zQNU0fzq}X^Q-)8#m z;B62N)*j9SHnv#Y96-y7S>UWCyODlX@PDZtIuDxz)@T40Tm_rMrP3N44PO6^U>7<8 z+nc9o?M?j#V_QT+;$MlZ7?o~sR-1zxU%xwNyVcp%B_DZE=g8uTxD4u<0hE|$V-)L? zE}i4uIpG6hEvUhEKf84$8;j%AMjm+MN_De*ENpZc{md0ogM;PzDXEBcO90vwi*Svb z{I2{em+@{4A-jWxZp37j;e!?qBhgrpARRRlP3rK*-qMi%+T*E9@^+gECZ>og5BJ22mIw7 z3$mg91yf)9f1+SgKaVJ}M!*Rs}q@a#5o{P5FmKrAZ4AhewbKhB;<8ssdya1sn{3+&f?afV9!4E&DCo?u5bpGhUMaNxCmf#!{U}(RVGr& zb@C1#a!&J18mrZeSUhiS$%R-bTu6c(A?WB{;P09owr%NIYZxR;k8(v$qRz|u!__j{ zf3t7D++Y|d&e}-BLOOd9S7)*6-eY~&8yKYLw}Q?vi2~DikF&d|pE0TMt>_`0LbIZy zoFq9yUyYOnffK_gV5MS8z(N_z^@sEdMNQ_62PQR#MS&IWrCnGLdKpRoMq7VZ(M@*q z0P9_Gcft(K;QM$6qh_tPF{777zcH--oVhRDmYh!W)7Uz>g~y2qb5 zeG?3rbA^3eTMq@HCE9`C{LzdX;Y6f>uy$r3Dwm80@`k^#LW{C zG|Y$uy`CC^K-W}iU_N*-uBb$TyJlLprElGhlJRW?hhuTlx2A?#)r zBhJV^-rMjw$6N;Cc`acoaHW2VQeAcIBcE$Q05#n5k)6v1e`w|DeS~PyMrttcvj77fu`=6_ZW>9Q(I9=1>DV=#V>xjLL&56Tl&@gUMf8tkr?g#Cb({{_oFM?;(f#O~^Xr}T#3))RI_;hylH0VDeZ*;- zKaBK6JZ{q=0?^BTDdR_(%CuZqvGA1c5Wud0^2X_lJKKiW2R|lnS}`vC)u&SJFkm_= z$_(EdHc+I+)o``-nyt&o7e+~=e(wu}laZuiZ zq|^NXy3jGjE??K1R7=g8j*0Ost;*xAuLI=I>Cb~yA~yYY8#(E7HjB*M9ix7jQY9go z&C}!wHlH*HhV^?`t6FSAf=F0CM}l`MyI^>`p!7U~5o9onCN0!I3hUHACXG^}MY!Gp zB<~zLM{CoJzQ~S;EuEP#rzqxKI5Xb2v~W!s!HRD>1&unuzE1U|y2mSVP(35(s*G$e zpe?}bxzJb^scf9TM0uq;UY=3=*|5d<*9J){GQ2Wtu|h^3oI)lTevJ;MkZb)p;WGAJ z^LxkHZ;KbL%7GPuGvHEX@n$Z0vVFz?bX0=7(pL@>`{Q;OPz}i$`d%)AZEwAz*TY`X zW%-r^9^YY+;5*AKVlJ)#Nc?aoX|OvgXv;H81zx+Qp`A%tS?S&h~Rfuv(x+3ltzWTuZ{HvHB zEFMp@{i-8Xp_hh?e7pvMrB&-ia+9nBvMHQj{DSkjEt_X&cmfBWt#_?u<|`){M##{b z{$c9j>7z3n<+us4OHHCbD)|!o*Gc(h6kUUM2#bzHn4|=@M{Hkj_-xOMp5Gn`WBbC? z(q;ydNv@}f(aemC2rHFWmNNW0FrhEYUbW!}+F7$(m6a!*y~H$#zn$S3HHKyiYa=~PA-iy1c!c*bf( zQP$kRfJsgQJNdrrda(PIexER1!E;oYDRXRLw|;aBdUOh>HfItr;NK?>~D zJr2?0`tXutit-RoxSkWwcCmgr3u-ZPc;ln{46)1d8H^!z;OP4Twzml2bc0If_kF(6 zVzko*n|CfzKv>i0ZUN?7l!~>Lh;BEP2Qs=DxX`_V*z1jx9JB; z=lWNAs7ujY8W2(W*1 zBx)p}2Qe6?0AAvbG<98J`i=2fpqBZ+$PPnp_d5vC;Y!k3!Y4G}IxbHx0@KIxqpHe4 z*uo|%wwVcQscR@)N~@sJMEzPT`SFqgi*r!HMBzwniT_vZux+Y@8)&-~oooUL?3e1L zIi+$2AFWmh32-f!{@$%N*iR@cthPs#>$FXAn@cx+-+({3fN=g`7GePs%d6tda%V;zMQJD{O`{5y*dsj5pKUz)Q>HvMGevq?4|5s!h1OLtqGi;6W}Vz$EE6KU_&|={K+Rig4zOR(Q3dv8^Wl0d)VB z;y@3ojzca)5*0p-T;gQiA3Q})`}S+%E~5-$?f!OMec%m?=Rr02q*6MVHrZgF_|sw> zy%A2MT{!cox%$g&-dsqxv`xR(59OWUC}#sKIdJ%_9?TQFIb7QRG3jm+!51 zoO(omw!u+B#SK=Ty)m5Pb{T7jL_veaZ@|Q1Q!MJKw+#^0p?LB9H4{JA<;IL|4qN!b z%RtOpQW!F3)H=oMD$2V)E(M_Pj%*V{$idJDBn3KIqSo)hWr-P;3L`)ycJaL+)8JA9 zd+_f2`MwJ*e*6E)9lY!9rj*OP*44@bv*-DVep0!XOOBGxc>i7QDCPgZjsw%hB3N- z;<(Uk~*F-M7~eX0}>#*PVTW2 zq5JFh8;bK2DZJ4K(qtA^kI_lDhngoZn>_w}@0{+*U_6){L6rjB?-;3qnH%W>!FJ)Z zI7p#J#TOrqG;vFFj04~Pqyz?ki}Rd)Ccj_pm?MeRhVhD;)#hzr5%22`6lc@%6GrbhZ4RHNc{u~0W6jx}Ca_8CqpJ+#3rNudkyb3L;(}_o#5$u}M`C~k9uBP#% zT!O!itdzW=n^?55{2NXeC0KqRdjH(%SR*0QZRqg}bu4pzPDOcO&bCq636%;zWh{ts zT*8EgMrS$1^<2VvOO~+Y{fQYVP)c6JorXoHmemEBwIPVmsUBvA@?{)KIICmFK^XlxOn!KQp@Vt3kk z(2IQD+ zGt+D3a@FsCd+q)S)(nTqvl75pXMuq3RoYk;x(2M~l=vm5k3YUb;Oo>c6V$r%)s3;N z{%A_}fyAPdOjp3f^re%9@vL09<|ic{NYxVXG`0 ztbEXtI?{7fDu4FG|&4PcV~d3^SEqaK~?Ua)Y`CVmo+z$&~WX zK*J|#4O$uk*Pp$OVH{Uf5zU6Q{C}xmj7LCBS#sw=*H8WMa?L{T|B&MhHT93FA;*HF zd1ho!ga5y`wOjgdHN0bDc+ z8K~|O6_3lxB+M9brAJS&7h><9)Olc{0PggGNNbh{3TF=Q+#`CdpWjCzb5a>iL>ci5 z&b&+RjJJF8$E44OUk|}e>{PUPloWEx&2u{`+m!#IcjyHGX;xDPAr_(HrKIgrGNWnv zMidv8kkK}az-hw)6vt%*Mqrn2TFhRTv3*2gqO(9R!IF~g<}|R zcIh0hAb|8wmNFapJBzb%?xq%UT;5<=zB6}|UP21)Z7_C)_6$skxT9c$f+83}>&H_u ztFA|upcql?_V8Kpn0WH3G_khPh9+ug>@Di#yO7t(NT74jfWm5wtx2079t4bv`qV|BUs4)6P>IXJ&91z2 z)s{mglbUK1yfku7h&sKC(FAH70P3z`acG{#&9E-&h)gZQQdU8gPy&0$KN2)rzBln^Ci_n6=^b zaat*k*~!+WZ_-)MpBEF9E#nZ)mFr~S^V(Sj9A&?A7nCcnONyrFG$qL%)&F*AwKKFe zn1O)ARcXeWt*2vtVOu<;+J|mthpgU2OoJ*L_g>h$P%8ngqG}=Bs?e)EGd;M-NlE1hX>TMzxTQbu-3E{L^;6w4ltSXf>16OXiLk8zt=8`_*X zQDE_EVl^~idp%k!uygPX2QiU(AYo#>|LnbR*(fwHRY;@Skld%xt}BX=^X^lTy2~nu z9gk)}+WAsiSX-`?>Yu8I@%KzrdIk*`+y6!N;G`$PndecFvEvzOwih?ytR9)yGYB1U z0nH_vFIP3uN zyo3;;%jCOeb_fj|P49Y|_+~k3GXe7=4vhEQ91A3Ubxza(Ka9K-39Fo+^k#+(g6JKmrJ3Y(}m}R(E^ZhY9lU>kR=V$ zG(Ny{BM8%ZH^cEskz=*`T4SgL+yb!DrO0`bVj)8dcFsMr zz%L+l}%@y2Su*%&uSh)!TTS@!e4)-HTogZw$C3)w4=0_Mi-08@qZSddjHNC^u*zYn9wF zVL5(Wk;G_~6Mm`UUDib6ZuiwmBhH`blog87;RNNX%mx&;b4Mg6^Zm$^UC;jznk6M< zen~%$t>zYe0n=ws(IY`{%!RY9n1;)9#e#|E6T?Sncg9GssR~ZE-tS#IN|nU~l!RIwPF~P@6HRbPyb_s(e>X?q)ND}>~(LRtiPe>@VzBs`q@HpQv2Cx=?=WLjRJ*cJ)O z!~gCX97A&Wt|!Dz96yD-IJ>0=#n4Gs!R3r9z>Kswo!TIsP0s5RbH#rr2@<4ayJmd@ zbd=?@??TLef|^H28VtY}(37I+psvV5538Mi_+FEJw0C-PiHiFH)x)Un^?h3RCu5A_ zU2|-;5r7tzzuWAZ_K7sDo2-g1!F69{lQlKyyV~D;+m>rWu54>)cfW)m;2ZtBW%`3u z-ee$Iy>;W8^qEg#;byFbWf@9Vno*m(pX$$krbiI^eq3Ij--_!fj(hEyh8UjfU*-rW z`Bbr&AUKKl;3XU-o(de_^w-8dlHky7O|QEOez*4*7j7-O)=hyQn`N}XBw%+7SX_VQ z73H(S#~DuF?}$?Cl*Q(^0=E$y`eQ>#>jTx zscG4ge;?cS_wY)z0J*qCHp+{V_h<^GGNHK^-ft~*|GSoTmvLh|^IzG$5^HE15Pfv1 z{+(I-sF0?!5L9j;U01xzn<*hsY@F?@W3v+-e2VqI*DFmex|1iWn2*BYzUxr*JA_mM zM(i-sVTx;O#gh3~L0<)8wGwFILvKwj>Ue$R7FEE@66AjX0a_NJh;gltsXVsxeF5fR zcdM)!nE*-SQYs&bCuH`7L<8Jm%J&)n`+hoM@DU?EkLd=I%;^+y6o)e!uN_snIjPC` zT!T?igYrMsAYI|%(jZIX`Y|M@iH$VS1xQm|^9b-g!yyD*ty3A93-KAAZtmUHBQj|~ zfPbILGn33Pg|xsC8rw^OGO`9gMoj`AW4|?zIJ72+$QKF5k#Khi(kI3LS{Fqqk4&fY zgLDaucdQ16V-aYgy!c?3)0;T+${)yZJRHu)6`1$J zmL=hVA6jzT!sVFSGLaY&$z{43Em6y;?Ows8{>2yIW39|4>5eGFB^#sh((`G6NXR6y>U`FN1Q2-r zpK}arvd}qT>#kscX7JxF)B5gNID$21;Qd#@&4jJx)TGUYQ2uG}s!0hkPcrPXa!q1aIOh1R8n{n~b4Sa1GYW9ycOOM*`grbC1P zd|{ZO?9RsjMtkIYN6F!pzE|zj(Q)&jWdz^vV4L}GQ=O~-u#GC*F!f=Rwzu)=G0w2Q zdUo9gS<+!{q;W&PG0?dFPfidUwYIF7$^9fSLEv}3V z9~xCj_{`uJMI@bnwex3&Vq1!<-bmd$K>@Lxs~C^wSiyQV(-0S8811!fDgh9R@`ll@ zNUiJlb*@7DbPycS;n9sdwh8@fmxlBLxiiY8ZCTlXf3!iBiwW(S;cwOGCwjndof&?Q z=&+G8v&|_pR)MqjPL>S+?qvH9)h5y0>xMttmKIcBG{%mjs^@gs`sA?1*RUCjwd^JR z@?K-V4c${sA$|nUwhaY%L71SYO3{uXeJE?$7*AJutO}BtE_i9w?4;B|maS@`w+Uxe z3$}ZXrTJfK-4gRM-id6iczDsHfX4j6typnN>DAL zwp3F=sHI{rwMFdvZpf(EDV+ozDIKv*MQt6eLA6D#rIupsrMb?Xd+yA9m{0Gg=O1{_ zd7j^gu4Us*h~)TsYsuRx1(|FX;^5H>_nC^q=o(31lQEBNUuj|i_sXXkE2-a7&BM{l z3T5P^y~59s-62y>=eb1n58SF@VFBD!SN^<2(=BW&Dz0O}`g8Ig8^tK*l1fb1Pe zW%pvk{%MK+CLXY5bC*c+h%^M(C}*g^vqak`gNL2N9LI!3jq2+C6RYPG>nQQTQdw^& ziNjybO*%eAieV?~@06Un`7Q=8(}q1P=Z&naXqscD$Ta*hDKz$RNc_3&H{Sll8xd!X zhM;}M7`fnh=MxwdtFlx05(9ip$y@F}tvrn`aP*m_r<5;CUUYxjFv9wMSu5|%gjx=e7FX8(M;umMifjrd<-8rNZaMw)WL{V zc7nAuug1a7ux6G1R6dmJ%17?LUucMFm|@rBKGLt!SfNF8C2yb?rS#xd5C6t|3|IZd zeC${;{RK)jt}%s$b^U+U(i-SCcDqllwJECa*J7MYk-aVL>yqJS$1XKD(7X%vE1K+4_9zDrDqAl9&DGw*$23jjm`caXV$FTD!(gK+3?*W&r@ zl03UXsQgc=2eC)^k0c`syoPF;RR-dM=YVSr-7)c2lEu-78MqP)j?W~H3a3`>Bi$5D zK1#ZgrIqC6(1i@aGU!>ObA9o$jB^LCFW+nGV8d7W7Y5WEv93Y0_W&q@W|+=hsUb)^;i~v zuf!Jpy0UvSDRnxsHY50~&h~*iOVy*r9+lXDbT0NvYIJSMj9G~<9!bNShnMOXm``$= zT3P{NYh^m?q&|#7H)SQ)GAlOQP%Zf7$%-TU5~nG_zChEZ`3PWL5Gsv&YQ2Rq7!;B1 zwW@!zQX9Z*EP{w6O7bBB&K4;Vw(Y{n@9xMEM2VV3nVtoasVxr`#Ua~ zKfvbZVq(>Ii;+hm@8QlCYlHe~hHoamO1Uf76N@flw;v(tQN2l7CncUg*opxj-2Ca=E^(`>~W zxDeRjROtU>vVkA?=l!3V{RuSL;E;gb)@8FDzV*BuWhP$f+43Y~qf1o&OUMSm%`wz} zk?{`I64bGFu%RS3Hm~d7ed}SBVuk#n$$20#)y8N6n_=)xpXce?szKBJe2W9xOwKob z4?*brS0kuiYHUpH1>ZrzC3R!pY$ADtCv}#L`k(bN+OqO@>mxrdEx0msBKES3_zV>- z_CkoB7w0*N@-59morjzj8AP!bK1I;s`CkRu$r`m3G2bdb^pv!v|8L_vS(ODoI7WBx}<=OqW_{&Xv~+)FUZ#$F!@V22;ty z$M~pYXx)B)4>UXV4+O_`R6zy(L3NuMHFd(aPMo}DxH|vKGtj880LulQCYwKvJ=^(UWa4j7;98;B= e{*SLG9n%K6rv8|15+s4M2*qLObjoy5J?;qW_s%xsNr>pP1 z=Q+>kL@6mqA|ntWfPsM_OG}BVe2wG(9cU0=XXnbJ=&u3ZQA*q8Yn1xmAu(Yq^xs8y z#~+qoP0k28APV2fY zc&eR3XiB%0QIw2^uyRndy_q0Yt_GknM9KNPEQP=CQ}4}()2z>pOYgnD1Sh|`Q(T;| z)?UQxHtCJu?tR{U&WXSn_Ry>BXW5ch<9*)jpQy;lK^rZ2M&T<;v6(LD zHX>?k29z$h4Ojj*e)(Z1f-+=}WOpE-9k2ZGnX&Ea`tHPkq2-+*Pk4Gn;}`i0(z=qn zKo=S{P>YDkV`}pVyX~;9ld~5mKW+|9@<2*pA|TZk^nNSo(4O5qbaH6hf!ucHJ_xW1 zqZN|KGygU_=HlCWDdx`CHGDE=IpJ}~|FZ5}*R3g(U`ekzqW73OKr)SV z$d_zC>*C4tb-3etn)Erk=h1wTdXOl4k9DZ(Kz^DtrJ3W$)isVDiyJeH%Xq2ML9GA& ztnF#$*}LvFdoXb@>M`;}{sd3|+o^2e1yt);y}UhmIk?c@G1GT2o!*Azppi#V9YGBK z;dZJoN-E&IV_A3X@oy*l=FsEc>>cfM_$`F*J`1jnF#>fbrO2sa0nzmP*L6J$p7}S%oOoXt0hn?u1N69 zee%rborlx})z|Hm-GpWz;7RgA z--k$|-Y)t^pG8N+DpbC$w{QvcSb5PLlCj#?2zAl5Aj<*ghV13eO!obJb2ajIG#w3C zxrA`3^Y`opwRjGD5(n|_X)k!Sy7aopUc2uwwwu2YbMbmj0fxO`2C02vSQBMGDltQ1 zP{3;$GJTf(N83Q1R@~1XzI@G$Y-66#py*L~k6f;8l+B#NS4scFQ+_^0_cDG%mxw|J;iG=nhGjD!JbqnoA(c=n~vGyjyRVRJ}+7$(Szo;zxR<8`C2 z`9Q|(!_+*89QxVxWCN4z}f+O9l8<|$l8kCDDAWPJgLnLsUhYMF_tEye%R&JdtFDNghu#bA zTkbAb{S;&i{?721wI;w$kbuZi`_M7J@yB)g)8xrgm*YxTy#pz?Q7>$F8t3ri)!$pv zxQjqdF$V%mf*tn!jx#9|QZDtQ;*pBksiUvOphiGp(Ua&}>BQp1_FeHw`IA3}lqnt? z7ic6v;vn`t+L|ZrO}#CRv2#fqH6{l0HxY8%RI-zBUi6Uvl!K3XD1S|^O+$5+ zu~4&BszxLbW;>RjC-d1QuOJ8_tfigMVJtbGsDmSJJdvD#>r~<1&q5c!6g~)M!A`j= zYrYHQj;&=kTxC2dkJf>eB|q9gW>CI)%dLM$^MdIdcp$cRoFmYf#)>jZ5O?WzCf@gwTFW0Wj4NN=gsa`}#WcWA(jJ6#ZZN)YY zEiveq(EHAw+iPyk&Uc0TKaRi5HjTjY^_@t*NA?+dHCjgUsI40cdIIV=Sy*{Ec(%Ou zZ!sgD%-3Tr5Z9fF;>O4q=(cOQ7c8x!5NN~bOv7vV0~v!(sG>1C)T=&+C0#4`56bK2XE7XG z(NJh)aAx6;s=E%O09!UutN3gQyczrt>?dMQ`!~~{KCJ4@t{(&Ye(*svFeGS}KF{TITd$G?< z2!$hPsP~4DAJ&#|G5GHouE_|kJa7D&48b;h2JfBt?;kYNq|AN;-fE4O$^Hlx<2v{W zP~Hm2Vs^7Zh35}N+{k{RY)GHGS>f|OPz$u~?UvrCpno#a(-Pp)y+wb6J)yoiadT+d zgt?yi#v4z#0H`pwV==}NA0%vHYP;mUuwS~;0>d-JGtdWLJT~X}@!(8-+){`eWiiEM zgrvV9PyxM*Hos1`z;{Sz#&Wz_D-Z1+3>qZW16b8pud5sL$0Gq0Aa_adWONCJR-CD0 zt}6}cNf;H~?Dxi}GUqJk%$UP3j#}<2f^LwIQ2ftsTZWiPyRmO3VQe4mxCYwfSp?>o z{1I)w;X7b~8+AQwj5wTNFd4<%Z)AqMRFC0U)tcl(bCdMyZs{yndYxuwFIu_3Z@A(+ zz_(Wz2^hB__#!mZNpdClpR9p~+K4W1gcW=lA1hn8xVGbpokA7<)uWvZ@#eYvZ_Jrp zu@LGwo!@3h7z%i*?k>HPUI=eIb@Vd-eJ{~c3hW%&xt~o~`;l;qP)|pq@k}2O{4I8} z8nnK54u`6XSs`K`_|9-SsW~i7s|Yn;v8~HcQfcJozfO2fbtNUT@e5gwxrKkTh-{^U zKry9DJOgvOY83YzzT~HMH`C9`Zl59G$^CuGPpQ-e8u$xOA|$*yhlm->xvKM;ZMi;| z$6txeM9C@9@am0&R0b5b7TtKh-RCd>{=wVG{dbFp|DEgvmu#3xPUNX=?kONLODUg$~*+0w$rSgWWcsT8Ogof zcu1d%5!Ku$*WS@hgVF3^1Ft&IUalio?h|XQHX_Ma+##&&8mUC9Xw&fzOh3|#0H*vI zU633I01BFA+`@e8-2KZ|5KF|$M!7#~vNKx&TOyPAy%0Nng8M{gWzYi2q;ZyL-viyS zKs>8ZEF)2?k4)I`)F#okQi)iB`M?QE-QP3h&udz6y@wam13YbkUf2drGB zG#yE0lBpL}CDKW`RpYB56D}k0J8>JtQbUJX2djB;#2N;6X{;e^8p}Hh3i+pw(o4DJ zM!HXKJC}ARsVcmbI`@3tYQ$O?WAjC$H#gtB8&zHlHP#_!BejnETq3DU=y@}wkH6XZ z_Bf>HeQc#RdwM>)i;&xdU(W09@DD`lpUHA7EczpEKY-(^ar5dfTZq|NVuVD~23rFVgXq2E!e#+8w71NNgVxtiKqH5 z-&_B{&4LwCR1JWB^SIkLXEOcHy%(qa07;)lb1F5d+wkt{yadyU0mXE9oC#l1^|AHe z?&_!NdmRXIR8ro^&aMg6P$QlWJ;8uczYCNem<>$Rb%)H80|V$@1{#Lr4Mg!M48Z}4 zHIwGScT**Yw(*L+^N85ck=w+TamY$qq)md^g}-oc*Zg!jbIb`el!D{!x}O83K92O@-KH8Gni;!g<9mU0A8Fy}fFD zEAf~Vu$k{kVt&XY6u|j4&!o(YY{@r{#_Ipq~J%jiVBG;lxfSg*~^Fny&+|y6)>Pki4A{ z*_sTGb}+Io?cd^JUX^oKmDddu?$xN!*-#r>2(QRcLZ|&Lgt^_i@9OZQrmswHO%EXc z!+7`=51D-5tc6=e3hm5F51!gO==hAtvhEqsE$)_g-hFcG@9ENxlXoY(&b}TKkG%VE zr$d_`x_zhNM5!PlV@ylP%%yAmJvOxlFq?1MUkFssoy(grh%I)akRw(giYM+)&D49v z{8E)eFRuR74iPK!D6~QKhFkP`Plprbjtu4z4tzforhlGYmOFAO`9yy0O2ZG1tO{Wh zp3F%1a>th85J8WYTUwxTEHFyWa5bFw2Ax#CY0>qQrEsu z-Nd?Errw!B#cjCF{Lib8YJe=jc4*g?KT^vWf>6FNgIXvr1Oq_MW!+Xxoe>36$oR{d4a0TeJo+lso0l<1-G!R0<8GLIr}E=ha-Tg{Dd?mSH`KMoU)%t##)UhGT9A)4xWE39$XI=nm_~YZvd5{ z)nFd8WtD6;mUpry;XGgh`GUzk8IR{#70e-U=G=Jh@CeCl+Bt4^VHF`?a_CBUHdD;k zT{d0(2G6A(F8`ht?#EgQa=2P+yV$c+cRg$Kz%Nn@&JXoBez-QDKnxy-xbmU7_#goc zjc3|JkKelWRqz)~f3qe#7vbC=IMvMyZmgSff=?O$wHgw3bNoFcM+9)MMF3s%*V4S& z_R{g&fQoqbnqUy5){NR4J(|=?ESToFepuc zN!$82or0?=j=>`YXbu}`a{pofEwk#{Fc>CilLod5488sqG~)UlQi93mSX4@^#;m9)uJOmL1Wfb_>l}7gb@PfSWP&=?as1lKivHqoedlo zDhO1m;KG*;vMUViJ^C^zobssOYS}X~ADU7akx-8?b2MQcdOzhd zHo&NVyE~uPK{sh#M>W8^eZ*WvBBA;&v<-)mh5kj!7@@U0ix@@YyhL2cJJr~m;_HD+ z>-LaBZRI1}@S7!5hoFn-Du-wQL+NVT21lw0H_j0rO1!z+zQkZz^!hmu3f}PgqJ7RJ zKCbxOYHuLphEamtG*KEtW|5VQu8temK7dvCLZL470fiYF8S z=P8mwd~^659#}vcrab#B{?wvM_(LIwW_IV;H|7w>Z?kXl zsp8H1Gm{FKIY~?74$zh-55fyNVh9iqMI=(@3_{}OGsm!XEr`Gmy9Mu~p8&so&f>th z#Wydyr-%AOz|Opi+usjcu8^=t;M~}LZ@L!a`Xh8_qyW`otO-#xf%s)F@m_9kxPakj z0X50IiXV(P_OZuU8S)TES=3Jj8Fx*tYXLvr{_3bn6*DGDrk7Sj(+3n#tB~;RO5q&b z0G?c)eo?!1X<&~BF+Bk~D>z^SEhqdXFlNiUOW^p~0gNY*^VMu}BaT7C?I?n`z-ZHxe_^BAVt4vT~~Q%xqxHi;Uzm{vF0lR=Q$a z)nDDowuR={h*a9)k|YgZ?4=o07c*f88Oz<;{#Hi8YxR)uu^RV z6%?IrV7g6+&=$ra3bgH%%_1`)9GMF+EmoVWYlh|lE(5haXkUL_X;FPebtcYFF0@^mHK`ee+-{l=_r?0Hv$N9rNHYC+ljo2{`&iLtP~ zNe8mi@-zb;(u9UT&(LUyVp0ikfV;iYJoU{XIAKn~ti0)jXI^A{^;~^jhW^56lLaAR zfMwuZk=9;eXuVmvN>rRMXX7VqnBzJG`NsfOBRsDiSs=8Wpv|=r+d8_^et9A!5Za*y zGiBE}7V#6Vl{1BSj)|oXA%q9%sro#Vf$`W9^w+$v`bXGL_1jGL+p_kj71+Lyz0MJu ztLMGye$eFr$>51OA1n1Uve^6qB9-gU05Ns4{_Mt4xZU0rO%a!Ma(O6o90g_G0rMZvAM1mv za6)}(Cz*)JEk~{*tTo#{d}o17<8A*l6nE*(8@SlvC>h!>KJZJT=brm;N}|hTt_|5z z8;ZOu7YvZ6O0C2vGTr*!sQM_zzGiTeMyR05n|a_S>!I0wM1cD66mlU={zUQ})Ja93 z*X>9MH|xLE;(DSgXt|7J2zO2B)@K-VHFKC%>8NJn&ht0g>Z++_789!^3oHk}FTY;r zUk{0wx(&JYZ!Jn`76K^{cu9>Mbd`!^puq=~yu&Gw=SMgU8_tYKM%w5fqf(l4$tkUR|^|ZLA+Xzt5M5yD5#f)~9qzv&$-r5V#^9_H1H+sQlnU zA|91S*r0b-Ag(J`ZLx)FI*AO>Eyb74PYt#^bGj<#d!$EjCG(1DzWD}wsbpimYTs&p zXXM^0+x!s{w%PzIY|CUIrxn6SV$Z~%m_Lz6?-8SW zWL_<;Mj%Ip8KH_CQb%Rk9KbrU)$#91Ga(2lp5RkBqBn>a0 z3?}D7(6G^*+BI@@*SP7tdF}RAq`h!%jRG%9(U@C-ch26at2?Jh*oW#>FI__YVVUg&_DhOG zFK;S=1!JR!UPb2;#;-v&1W&@|B(LJY-kjgs>0OF6( zht~N`l`iB@$DRGsJDnE_re#;^^;m}kwqy81+^@~U1f4R+jHqaXq80(C|KuloC6RMG zEUWGW$I~+65PXnpDCux{(|F`}j()7Mu+TDuxG*7Z`7wWmBtUz-$@RW(Knl$mfS>Hl`h^9NUyayqNpm8p%5 zy=KfekOVO)0S1ZqDz=f42xD@d1qJmlv~4R|Ag<2@3SkCIbJprw)VjCNXBTYm6q`P* zu=jkQu$>2?p1*rrgFnJ;lsN`X!UR-d(h?NrsAkF;VhohLG-?!Q#;J4o|GtL2MqfBX z=yKYCJEe&>>Suwp{a_(1Z?w0Ug_+`A-bc~)SL6N_jt)C33%6kwsb*(CxacRVHDeut z-#+!dgqO|HnJe?vg>)st$%ep&5wtb$$vAlAHHM>#-7nSYhtlxPH^d#WftROSdy9(o zxn(rw2HX-QOA2vwNJ=R92~eEejL_-jsgP&bgWrL%xfXW6tFQ9!h5v=Sf z5G?yvLnMzXk$Tr6Eqwi_F%IwzpZ3S)gz74a%f3l!356uZI;rr6elxlSWGZ9dX&u$= zrQ?I+QNfDh`whvnQcmO&q#=FUWM=$#mq~kedG?K|yrf5(--d%u)jJm2&lDELx+RDFX>4B+;fkh$^(JT4Ev#~NbdXaiH4c+0 z0=nhIx+ueFvx;#diS0csF=R7Wdvoo~ve(0sAX3#JQAUuZeVQ_1N?|8>724AbU5drT z;=fjm{eNN{)o*%EtgQz+4VxX?FWx_h&wc&A8hRm;vo{VzTU(p^5Y|j!$CUa?KSrkf z7wVp|l2j*(__D7{@W>bL$%;HqI<7`l5D~v+vnaWnJT6(|N&brI* zTiOYj!*QmdDi}zVM2L9@%UHDenMSLecrfBLMP6<6Xw5f8-(>v_i`-yNXbo zk?e{TkYgjeKTl3yR@>dlR{55jM_CibX2d&$ny^kDo#FA3o$AQC7*}4Y5Nq<07Momq z!VfMnB;;r2sLd7v%_5!0YMS9cNAMJ3^RM>P$i)$qs>WQ^p|q0rONomRu;uB$Y6=bUbOi1e-rI--TAw_(klTuB;>VD= zaXhrN#%EX+b44U1zFc8TgdM z;tE)Oh31Iyh?u_n)P!;`>7$dUNH&z^Cz8q$?FfV?mtIR{s=Uc0-u#M^2y>~%Fjh*R zMe`hbS3^N>Mol=NqLaJ*gbJsf4l-CIBVnvph|AiPmJH8CcNkV!a}sncug#&snn8e2 zi6^%=1D~+0?!P^XYl&!>I9C8y1g5=ahW@=$3Vei!bORh41A=JS4)Wr<2!0cI91%QT`^D2)K}`)*9ZB;9>$k;0@$Ql=pz91$Cl1X`Y&_ zReKN#X^5>8Ie=HKCKya&k{dc7X3=`D7gLE@IijscvoP029H7O zln=i4>{hDQa*9cKVg7;pfQ=16J>s|0!{Db9&J|40np&+ywTfNKf&X|=`7&iODq>CU zw77}kLal=>R-i@#UUt^hSbtB$h@Yk-6Jt1mnt0KUoR2G}6bQ{7rc2|ne_rxzR2ZiS zYf8fmg%^&O0=$uUG3Ur6QC3NdcEs(Q& zRju$G2Doh{bKaJ0_%nH!O73pZNU*vD!X!Oo8l4YIkM*l7LQ|WY5WdvpT;d+UI&GfJuhegYo(F&N+&80@TV;xukIB&i!6@+k?K) zQ|TT|#H+G~*7x+ERqJ(USGQ3H{}+7Xdzeq7L!+4Hf#X(On<|Ww#UH(OI>VE7!YB<4 zA@z8TkLCN9D&8aMKYvR-8HJ*F#dNg}@@F;%h_KoJXJ|G zB2)92^_90I3N4A4#98DKzdnUOQc8Eee0@tE8YSSg_OO)aGvSNOFW7x)rjkEFCAAS> z(249n>%Lzt_-r1lgzR)YQ0c29Cf+(|N_;kdI=-}Px zxO-o`?YI{T zSQSAJ>x?)ClnvkPFczFKZMMmmBzX=}ZP$xzNBmyv1 zUj@ob(Zrt!=hR#6s>Zp^QW=Of&XqrVkEc$w{WY;v_vsqde{H%>HH+El3|$spe(o{e z<=)g>zmJBjq9OY|zzJsf+`>MUzXj(%o&1^yYm&{%Lpbnd+d&-SkTzAP#+w{(bISff zBvX=hly{&-gwiEWuQyBMLnZrx^4eW(+lk#q{|^G7$#&0s(7kukgGa_S=ET$r#9R;E zoDJX3*>qQx+TKfRe)0CF-Yxv<>_7dR08FEz`uU!QNY33Du5Sk1w)@N^N>puYT-}WS z(?_^!JZfva8qT4!m{QFpWHE^fo5L~Mm@(rA2G}jQv$+G?r_*YH2)Q0}YP&#NDN(Q^$AklcCkd6hkr^|T~9+&{{u1;`2%nL zPby}8_zaVMGlPU{Ah*;$Dz!AzWFH)*u=W0h)7H-3k_M?MtE%PoSPa(}Gu3yV(O3>x zbkIXubEi6K)%qsX#w!t-rgj7NrBuOLKD3tQ9zH~W=Lu3REpAt8ug%#B%S>$_EK*KW z00qef@d6|ji27_pJCE>@@2l?0D-T9WzLQjzM2pf31mQ73;GWVCNZd&g>=TqX31(KK zWI^}Yy42yPYpIy#;#GS#Jg}tcm(rObrK?8q7kwm3c{!?0{Pnu^P-<4&M%d!eAg+AO zETE*(vmqe}A%lAowAR^Ss*RL|KQH?tWdf={tz_CXEo6_-(7E@eN13&*o0xe0_2((M zzJJd++5EtM?fAv`wIUpugKK~{i8vBdlbS&BF@jNu8c4CMcxK)G1fs#bVgQqiTCoBK z!Fat5)^4B#QFz56GgVo_N>IHN+ITdP&6O=m3ag?a{v_UlAF5mesr{KkOUKuK=BjT3 z)ha5DcX7#&hdgHe>0j#we-9>YSN&V+{?qK>NjdWcTRrAf0&Hdp$&PprGq=qm0`zqaG^2!@Rf?))kmp3j!Gaz2j;uLN{+guBDkyw&3)AA}0t`z;SP z&rOCkF1@hg`-SMCe&no~{$4myIe%NZRM=e~7Brrr8s7@)MYWK~B2$0Cks7-V{gtaU ztwCALV0i&vF{mc%1E36kgA%FqmdSig1pBIf*}tyT%(`^BE9AeY{>XDJPRklva?Bq^Hb66GVgupZq*sxaW9|5i3TbQ+A7r&Q7rcsLMYG@|)2_ZP^|RliBtxK^ zl`m~7uo~GtSq_;jkW$lHP2+{<7hRGE!ZEg`GAg$+9DpG(1WxbdYOYEDTL?3>xO?mX5Y0pjt>WX7K=c|hwz{k2h|_z% zqet5%6Mgw#vp8BGTs@Fe`e0(>HGiomZxeqwSvuN$k^!s1X3* zNQUfX%t>cU)=*?YsT?!^J-M^jjBEq3Vki6;VY|qYTRX|)X)?1gBC-{%XAj2~Vq%z1 zq0oEg{(WHt!79H5#G_}xT!*d6!%lyDZLoi(U{Xv7$qjsv6 z(0l&@<}S?Z=B_C$D5&EDs}fI@Ja1L+29}_;_kzm50}LN4qxihXk?B6*<`rNLugnM*dx0r_$#R;OKlQIjKM+S?Mwst-k^`i)x9M zGItaH?iWA_HMLYtUUZVO3YRABA}MbF(78VfL^(-M1zXVTz%Xd5ywAbM61`P%s__gZ zDaDDZFsY0Ff`Y$rSB&+`pNOf9n8jn&J$%{Z}q9#zb9^z4+-)w5Aw8JbX9`LK7nX1S0 zOf(V`V43Ae@Oo{nKQ2@2X`1NDauI88LoY1~iu8M8KM#M=rPI4SViuaXMIgf^T8RJI zhN-~~iDeNI_EC(>B|TaPZymERk@_Rn8w=%XuBoBm1{vHhUvbtX9jw5MH(WRAt3BvLDW3e_!uBNUj zbN}m5`e{A2D6!9k-b*M+J~ie0x1gm0Pd5Zgc+ALji}E7gt>&79#pLEfRiSoT?H z`fr@ejt3TC0~|jI8ThmLz}#>h*Nn!}p4XzK=<|bBmaDs?ZFZ3{xK(L@vHN)86k3zT z2vZ>YxI+>ZN*0k;f=~DLszySFoa0gZHUE{Z!W9p3uN?32i$t{}r5q$yw*s7|CUe$P ze9nag<0d^HPp6C;?nC~=>duvou_8WK;^CFR*YrtPt%XUM{;ZMd0th=Ks1lx#agT_q za&^6XG&Ov*KN#N!ndkXS8W?3Egwv-W2~2#}Xwi8NM09){oY1gYsIvX4+P}Yo;XwY6 z*Qg#ZP3^3h*#s zx=JCY>zk03&T-0|$PUJB3}K8Iy7qrhuivJWjiCf0T+G zxpe!vyHaTjjsJ3SggS})x%YkSQ8<=FBd4H&hoPx7$j?G@bn^Sb`j&*g8I^Wl6oTa& zMLeTJ&>9TH7!dx}`%7KC8{RFEptEVu^uP@?d$0JQf5T7S;!~O;}xy~I|A@aT~q18)#{S+(`zK7ciM|}LA|9Fn1ku0rkcep3^uEh z+uE#SY=dpKCdY$ei6;5dV~x%Yy6WH9(VTwIT@Bc&GCEfXf$*x8t&YB^>|-}5uSkI| zZ=6>d~9t{T}QaNGYlI5 zzhhgSsd~)hON05G`ls~lIT@YpOd6Y0qlWj@_Zcx2w{hQQJr#W->8W8M)ZK@7pT$-O z7Di&0Q!K7o_}u3aOO9O^SEM9o{rc{gf=kWV1WU-o*<2q6a@6Uil&cZX63RmJgP2GafJD1;%_3-Y9VuE zxf@DX?fKvP(W9medm-WK*5?gSX-I-J^fa5X^ZbhM7e^KX69R}%5SBwS>q&jHi!Drs zNY0V|5Q~StE@}q!`FFbi5oXu_VSjvzbFLLw4W`0~q7xxJ+VR+$kw6PJ-xt2^iH$_y z$lr~_&ZhW#Hr(xr_mz;N9@MA4mQPR+^*_=p;gtZ<#hp{>nlYEuD@(M$rSk}iY-?w@ zXR#JzW-0j!oKMxLL1hS2%n;BBjK>>h_v;|JA78Nv3F`qzJHe?lt_AI|jv-YqE;Wc2 znPit`J9jsIvqB83K7x~jpKADmIt5-b;_MkMX2K}=SE%al>SXV(?gFwki!cWuPZcw} zH6rr2xqtr%UD;bReJEj2GF5$RetgB5s&mP(CTr@6SG9sAYGv`wWgg3O5T9hkU#o2} zxRZV3o}>C(F%8}R#I-la&5WXF4f^hWr1s48yiAt&df&F1c}H)S;!&lc4t5IXu{X<1 z{YBS*R7-zavbS0|l4k&=k|b5IR1+Nu-xiz-xY!F4lr$~ZG?KFX8kO6a@%g7VwQ#pWpk7V4yJqcE2rZRJE5 zsUcH`tk}$ch7d*5#hUHe4c+5sTx;F4SxjlXV8vmei`Vxq<{1sOY@_t$u@E?nm2ZU- zx_HrnOrXe)E!){mVIu(_frLsG5r`_7*TKL+aHW(N% zsBSi_i*STlP<~Oe^Rk@2-@jTsX~xD^6cmlou&nrFgN}M}xChd!{zWwC34a;EKry(A#Tn z*Z+^)74*Mt^*p3p&Mm{o(2LbLbKmCQs8Or#`NE_*R}}18h+=Bq#QdrIhMl>AsCka% z+uO5<5$qAD|MIUt*ZOTy-`MbXY+;Hk9Z8Pa}b)LzgPK2oX* zQ~lHBO}Lv+okyzv0Y9>VL~$cy9q@2<5b8VK*sVW4{RL3Q^gGp0=-gejES#M2O}-7XHiDQ6bkWH|>)U62B1tw!$Xu zbT$$1=T@HjN=T$MO_s%Zn2xLI;A+ZyD2=BKK#!;8o&z@Kp51qs{Q8yyporZ#m@qKz z;^Vp*3vi?LKC@9DpGecU@k9)z4H-IH4TsR=2027W#3-bihKjK0OO79&_0__qY<`o~ zgeVC{{E}+onDFtp>D672*RT+o}f#GBf`9-@BI|Mp1FR1lH^YK zSZE-H_`Q#P2!!|MyqYu5H@hLJSF<(>lHZ&UNqY^l5z;0Xc^GCOESpj@r~E655kUQe zW+iroeh}=i9cTvl&-1Fp7Yr1a34@Lolai#h1EX9+1Pfmff)k?gML4ugM2`_~vhf0o zj919TSR09UOmwM<&C-sz5tXby70!jq;N zQV%0Q7z!p+D5D~P&Sl zt>s2BZLwRi+Z<;k0Npw5+TVUwc$0D&At|KLJBhB%V#<>0RrxV71flfB?XgB``k!%# z*r&J!(BG|a*>BchaU0V2fodQ&A9a=P7K4i{R*kSEHjNReKe?g?*co)Lh-&!kwVeHZ z%Nq?MUB*Qd_`i?_G=kfHaX@e?qQR9~Z7frP^U6n^_wyX5LD+jn*4ND=d^Xm*{WjI?Ey z+Un~dN^ANoF}~)$WnMDGjk@d6Q%~uRq+Wi71jSR0FxmBT=wjQ?S6 z7frbi<`yj@xp6a4tDJt}1^GgcqOUibuN^&o*X8fjzS+mbiBel^1_z2}n;#g9SXGx= z{88kM7TrZW1Rrg?cXqq+UH0sBN}0-xAeZu}NTAr(F-lUNSZ#X8bJbA~TWX-vwpbG_ zDvi(v-^?@dXkeqbaB_`PMH3(D!4C$5Zi0<{BB4Z24%zis!-Lnv(0(%_#35SGOQu|> zCI8J9mq}V-Lf8X~ugzPC@bR^2+Q%N3Ac`jGbU^e(hBakLObjVV_Le6z?nRBgUlCbb zKP~9-aFerY=SzotR@%O{)F0~pP$3oMar!UrBcSE?<)!O}2n#oJ{N24~zG`{;@Zr*u z0zYy^zJEB)7W<2J&=I>Q75h`n9`>DF_5~$pcXyH|Xq9bOW%D5GTMI&JNN~VPR5cI! zXyAd6M%ZV+s_OC)aog2w=lVu$5i||;B*>YEKVLX`x3rW8gW1T5Ki9)D=Q$yj*(>~a zNpLh4GMrP2S82T~b~1zf>%aK5KPO$)@ zrz4*8o&VtCcRB7O_WN4T!;i$z%TxXg%`n;7w59^*5DU$fC_7!laA|KWlCzeoYzftzXU$dBCU&G`A_J6LeOZh#zn?}gOZN!AxeD9p<@<1zk{Qw&Gf#W+VJrVc< z67|rsAKi>#Y(lxsU(_YxE`&!YpXcs}>1#mlSit{>jq|+JHO>jngfxaLDyU6S@5*0l z&+pADC95wJO7YiI*NVSGYvyQ&NM+hMXH%fK^e5FLioVzDqSO+2^U?9znQ#88nO%c= zB}U8DSe($0F%0?}7^oIg=^Rc!?kI=rFl9;@QuIh<4-S?`l}*Q``zC`YV(v`#6$d6| zJD2hoE(=X}}ZH0`RjHa#oIL3qz;a)frbP1y@~s$6Lu5vXXj`Vhf~D zu(8*OApkDlEc{TMR{E{fK}V`di$+#N-OnB>TnYPqDZtx*_EbZVO19z zChxfxT{QIe1f576ox^Cy%X29r*s-g{)XnO;GIF8~6{dYMn-f|wQyHU16Mp<7P3{%bO< zDaZQFx+r!-qauyo0iANhHG)*V4vOTL-Hx@cgHFD(I&l_;{FJ_g%f#Y$hCj?N^WlDL zTun+btG~d|r5ko4QolE-e+WtyiqMKsK<`5QlTR~>+WD25BD%n{={V5q)UErMbm3Hs zSusvj2jB*Z&V={;Je}GT+w^{3bqMXE%rEac5ux7QR?dlCYyxMxD88%0GWIIUS z8ofG2PNGh$;ZCP*i-1i5#@OaVVB5EnH~3FTKmVKc?!BrLmlBEO>b%luPi2hW)#=Yv zMu(u0d|?MZZ?)k(J;%oRkAf*SW^lga3Bh2NE8ewm-W6 zRvoKL{c6w8k9X}s+l5oe>p6m=6+`z<{+{EvLRM9b!yk68Jlte{&)E`$6oX`oIA^2B?YXF!f|xf z9R?0m-D}8iho8Y$^m)MK$|6*3|IZl;nc-HMw#ZOnL7UzYBcqq(q(JI!Mfp1|t#EY8PAR(&pLo!X^qA?5U z8xGw;(&|*#Xnod3#iqrzyilcR|M>k{L(9mY==Jy?5Y_M)BCXD>?LWh{Ai}2x`!Dv{ zO>fM@m`I(?s%YcB|E&4m0tYAa2&;B`$8S}iRl8a26z(`M`s3N5h9*IWc3OBZ0mTvQ zsk??(2@!Srz!B|3iK(2nS>rgIcvB<6v<(xzcR#6qB=bN~M4_o7fH+|1#dVkYiP*f- zAo*e{4?DYQ$dSM3HS3>ZWdi1_x=8Vs_X5FYwt zeXYof^vlM&BlCHeh6JzV53$kE`;LBqc8W+Uz3Iz0J0_4)RU!~PGLGQCi1$4A7^U{0 zc(klyjyC}>{T{fVDJeAz62oA#y>m}B&pk~KW|o}~oW=lCAF!ga(9R-cZV34U_tw-> z`?RPSXl3>o(Dk!&XBQR?`8d;tojCcB^Dh{C?CRQ5Mi7mu9Zz~Iqy)J6Wi5yqzoqd9 zR;%Ue-Qr_kF>tkM_#&{Zr)=+jLTgSpPMd+aB?o|2Jw`TxCW=aoCx_8gn~aUX#;)M9 zCRw?1!)z#9dcA+5OjsnZL5Vb_e9K!B0fZsi#t+!b^bB!JXKQEa)&SUi`*I6Xa{L{e z>w>}sVNAe$*VL3IL5r`Ja@o5>mu0IG{^4Nd_eL+{SG z^u2WlW)#o5aR-8M90`n=Q@F*QOZ8aNu zUXvq=l#%T}ij%vRIx%^M%ZGFFB$F=;etduen)CzI7*L0wMm(T;TG z3zQMErC`~j<%=mFA58p90E~V1JI9jJ6pDy2#Zv|!EH-`zb%3>*z#X!js5(dRMCQu* zLyJU(BQJ)GSr+~SEhhhx{Q#GN6|4=E!`Lb^wIir3%@i+z4S%t6{Zq*sqEB_W(hl5% zR~ejgTt&=@>%MfHy%i+AP|AB!N#Mt}anU-J8-OYr+}&Bc$h6OP$>f!ZrBfxAUF+BL z)t|H`Tir~T!)lXe9NJq_0$xUe_hB&JC^@q*@&HM>45sH0;T^VKn|1;k*CrnWK)|%vQ8BDCym`JABw*np>;b;KBt?{+yRx2@0!sah3fMQHv}K+rYGwK zDL3$Klk~W6iE4F|=Z=f#=4}q-lV^a~M&QG6Vh%xEHl`O0m$D!`dCigLq#^T7V-C_w z#dO(&%NvraONPvl?LV7)W40n6U47qFXmO727xmLljZMx8~9 z19`y`!I$A?{9TXY1(8M{;;dOlmu9T8It8<`WR1!7-{;><{63_ru+HPPdLS6XE`h-h zb&KVKy=eAfi)(MIAiR0~!5;{9YvREuhyg#zSQ-stKSjKm=kGG6Zr;9Q*?KqguXF@u zw{47LZ>#r>ey111J@fjA{oNrN%Lqcw1o9^hjl*E7)N|Io_TYx>rAI-Il36i2KTa+I zOjj6Mv|(R0k!#%kcW?GqO*em93hooRzYN8E!f@mrot7V_a3=`_>g!4)YEG$3v6W+nqBwPCRB5;AZK74>@S|S(XaYuQu^zgf zVM&C5&d(G@ClOltMV!P(raXGx3XfWT_zSrlVC$GUwGNAWDi`=(UO)EzM(k1@$uuc^ z6}HTnNZw-2I4k9XAJq?bvYs$(YqVrT6*ZotR4TZ2b|)jA!srZ*#E~5{$A3GM!$eCR zI;y!p@}=&}QX5kC;uK1pIib~UmK9HDgreTxAwZRHAhQ*bBYsMuTz&P|iyC53O_zU< z$;4osg5s4Cr{*+MFr6?wJg^ZI%PDDig-9QUw|C>-QLwMOkE+fsTilv(rtBt?I;;r& zflH~#np+JS&4b|pyM{@?%BgMS;;<>-;2LWe)YP!j)DcoKUBj~5x~ecPdC0qcN=p9i z@b@Gzo~{S02D~j@p`nIxr@tQ|HFYBGwDt8+4_{8|{q&;MV79S2b=Cu7SN1c&4in0l zwEURRq$Av8%dH}R+V+dvL3YTu$;rA=P&B!Q=opXHy~_tID!%hA)|`hA+n-Iph^8md7@?ozw=k1vcL-qcSGZucvlk$a`pLzDEv~5TRIdJM#T_aJ z1vyt!=gyU>p}o?Ev~6c$4tXgWwl5H@N`fVbAM(|opkRZ~ zx4lF7q}(7;`eD6N9e##|cT9QkyVWw@o~yUP7(Yz7a*_hK<= z-gXlyn~U{~ss0Upu%b~NS*ezj2a)L5upMVs|0r=(kGt8E>h>u%a6#2td=~%)LgQmC zX9wP&i8tR_97oUX00tSo;E4$`l^i6qTKeU$dV6E*Kj+IMC|y1K*0 zbQaep)PZTsf)=#HLaKaA#RZEWY7}D7pE*9ZGwdeXq8aKG#ZF;tz|%8Za^zIfsM^F;iOauiuI3*>dQZ^x&sF`=KMr1Ke%`U-(>FU`$;x@&Ep0AN}VdM z&Jaxtl|(PWBW-_GK#HllU~O*KNyR`nHD;*@^LJ^nDFr)eEr>Go#}PL^04t0iBpeqD z`%vAYdQS3QzUIcU+x0Ub*-6d@p<_xy^DKERtvAXm_OU62@m#m5_TQH92%AsG5k#kE zr0(el97_ZP|M6CmZ3H0D%oi{7=K4-+OM@hzRfEfIw}}&rT7r2=1{i$E1Pxj=}5Cc55W%#uAnATgB^(*(Mj-*lq%icsf#gbr|9MaPh zH6gq1s29FRIjtvfh;H^3!bNe}SaT0I6-SU~Q_169;-i z!FhOFHt7ASqg=Lu7lq?sh z1PKSEdiB(%5xCds)`Y%L{H9VHMMNoiGc3lNwUotetCXXD60-;rps7Qhk$a8`6;~;J zd6%}Xcj(4^1YJ;qD+&1+a9BV1jmj&kYMY(|(fvchUq!s29!7e?V8~^n1^A4Xs#rKj z^N$wbd$%V~cLnZhl8FzssSYA4(N!UyDLjm%D%`>p>CkKWn>>2-_R<6gB3^TVstbNq z{GQ9GlNIi}V|iJ7CuPbZCiUBgju<9o{X&}x*wSThKh{qV`U^r?mn`ouxj@PV61UNI>B$9SN}I9cZcYi}Br2Syv> z<*VxEb9>jPtOpaHVU4NR_uIuMr!@t~N}_H{H5DBF4y=DLt}y0Hma|OgbfQUg_)6pc z2*|JVgsA=+q{NX9j9`$t7;jxUZuLd)*oA&HG`fBVud4QG|2PKr{v^*|lQ9v!tL+ST zb*-ump1mjvWIph5iTn%VPu=;$=EzbSJVs#~zQcHW!y70IhbKpT%Fe)@3G&$NpEDkS z9ZAbUi&kTzG~K;_A`IL|Lbj4Zd!bETAUlNR6SBchtTf}MH_?eunu;bNPL;iZ`9=S} zQfYBecbrm>c@Mp4MFX9N2m+!u`q}csRWzeiI7j#QCy)dWB|B6cFn%MSpo=ikbHe&iN?{XyKdP%F<0+76b@Xy82R%~%-1VnjuNJI-xDO|x+d506?P$Z%_o zh}*98BL5=}1Zj$v2K8#6!j%hZMM~mkjJpGl-$gb}{Pu}3d-sHmRt*S;?%B$VNCxoM zHi%>p_(w?ljO<%m1~fznuIM|9WW-BEK$AG@GsS-wr_=CZ!oA~e6KA&!_khXAx*caP z%h=c34T&w|i~31Cw!S(vz>Ips$#)0=w&0fcSZ`N%Vk-O)DC}4AW+XPcb+ZoKu;y$U z;Eo{$7lzn9+(Q>Un*7a?OXzM5Fza$7BUwP2&yQD`>$5wbT&uY{7FD4OK-9%*Zo+>z z_8{45pgzO{c&UqclC9kM>}HrdVdRgjxGpxp*I0GiT^+$DgKL7tg(ZE3YbnJ|gUmUi zS;B>mNr{=HOtWRybc9?r8XQn<(_df6v!(i6E_v9MvLN1S>Ko4yDE!6StQs*#)6I?a zcBw$M)#DvXD>&6{)QmOvqecKXzyr^G9^d&;8{@Oa`acU094UiZ6fq*Uwmf$AQO84B z-Ro-gj~a_5`Akt zL`iBibHVwWw_|uR+J+Y9w1oPqyycY`B6o2g-W-S-M{WD~wG8ICc%k6-%VFWP5$;?9 zr%F(u>0P3rLPt-xgY~Qwo~%|f3`%jeget#p-5KS|_2eJc7&e%XD(bsyoUyL`HPWU{ z;AD`y@Glk=Dp-48HQ}#{Ud&o*y*-Ul9KN6ANdcGfR8GFl;-ZP^z%djy9X=9#+M#HR zjg$Mc&pP)-CE?0((ZTo&7V0#3~eu;ZzuR}k>{LTtw>2WdGnMLg(TZTUV5 z70pWa7>r6`5V@3XmPypMdATkr3N55Qpsjx_|3Tbm`fVC8Du9x+NhQMOeHuUGsk1v@ zh-}rGF*L#!v++s{v`h4ZV*k5wk54CWZ4{L~#Kqgo`Yi1FjUw zsd?~l?kJe2OVb<=!Cq zz*d`aFi{B*c-Om;L!Fp_t$IB6r(PH~kT{ zO?@pwr}r~BM{-Q^9fIkY(XpFFX}TfXQ3O7-tu2D zP~t)A*eI5st==uTEYu%EMCerl5JhDCBhYAa;&@C~*6vxyhX$wWof;NBGY&R?Q%{@Ng6I;415w>I35fX^)rf^nukXf6 zgA&cjYdVEiJbG?`c(xPY6D$XcNNCb;A-~AF(|_Z0DCgIoCfVB=hlMQUiz3tX+^xZ> zes|ezAP{??&84{i#FrCk}uYz!tAa;18mJ)zCme#koyc;(63aZQRd8 zY?=S_)NjuS7ye;dtyKUzXg^d-bn7dItA}p(vkA#Z{K+ald=uZ|R-U}Q^b^Vov3gr+ z!*ZTUoOWztus@?C0`UEX6$gq8UT<-Q;5$|MyDL@FWVBG2y%cL6@$^qiY@SYwPk21| z5z_-_)lnFwXE`bk1lAi&t)Y=HFoF|&NgOQCqPk&K@wKZ+o?Ai_bc$JsAPB}ZLL*$> zNvl083VSNeLr8pJQkVr~PTf?P=`C_k<97&Fb5{&eG7b`rKoI0JYKezU0^5*-rk&3P zD6I=rsmz9Y;Elx+*q{}(kisl2WSd+27}U=%n+^-nsdD)>^h@=Iwx5#FJ$3{FTWfZO z`p1}a#Cusq{B4+3%BSc5aKj|}Z~d4`dbcHi{b=WY(zeu_n;dGH{~+!ZiRLu`9(AWZ zwnFU)+-|G=gfazFQI_$|L9BWW+2+hhBdEQE5>+%YZk!z4^T8;J!dV^iBer=}j-yZ# z#x;nySN-{eaKi|L0a#ComSALwuP}*WUW2$D%HG}tTQ04o_?{trw@&oo(?9-fCGG$m zJTMPQhm6$btPGk)15v4Nf>j18JqdzQg4o{1RvWJfc2*1p4g%O5zTc_pSvtsqKYut? zKdi^bTfP!dhM0G(u1orozyqpAag9FLB8mBYE**ivHM>d%$bs1^q8ed@hV}5c49L+H z(f~;fZ&f%LQy4pDxD!odHL(k5&I>#ng{+OnTb}y$K^2==f3ruBiKKVd_R5hub;pNr zE_&bNgM|Y%C-MMw7-C@Hw_{~RV~buat*t*>OKKH)i&;ZulSb&q65yPHNN+ruxaqpc zp!!sq{Q_^WrO%~qcetIlTl+VC23TO5N6Rg0F=(7}V$Z~fy-Pd4H*IOFFX=Pj-f-vB z-prSmCm7;su?ikN^U~OFAaptuFE0NxKdet2cU4}`Sln9pHk)?es?kX8EKb%slqFuh zPf1z&U`)!;)QTNF;dC(>vI2~u<`V-;c-T-vV)31-*Gz|~>n5ujfP3n#q)qoaO+*vg zce4(>(aHGwRyBXJO@){~gVFU9&kDn-V#%VrQtm^ksJgxRgi=poslL}^=ZzU|ct&?SdwB6^SeQ#cs zykhObKSvG0+0El&fhoEri{0esD-Yq)q!{HCWR)XOz_TGyQ^i-lPnBZt=8}}ZXTS0V zoc#lg0~~I0s1@^y+A<2=KXs+|uRO$-2NUhYij?H3K<4hcP6seL zRR)N%+cY$Z>&9SBF*T>Z?wn~)R#m7VlmpHh?!q;*f>6Rrdz$f;6z4s)o0R{9>Cnj+V!=0N#EgE)5rRm5 zblzSZS5_oSxAY|@DD@L_e6X@K>G){90AxUUMQ9=E1qCIH-lS7Uo`JG;P_l4XZUxS@13ZzK^lv$ z0__$$zpCFmU!NNgdZp$OvsL4{X-rq-IqO~C6?NevqgrAaHl1HeC8=TZyS`oc4Pi}e z5^X;V_UMGRZn7}@#|jOk)RUrv4INHTRf{?kx^Rh;VwOq^t8n*6tkV%0OIg zw|2#VangMJYJVkRCRc<5@me9R-QZQ8+W|G&EqWp58i6pk<&aFxQ7EyYP$iDeOp&sf z|E8wpR?smyc8hlPt_Q@f`6uaOt_en=3`ZHG8AgG3YQvZkPtKtQ*lhpfMY`IJ5aS4{ z(oxU`7w>B?p$>-{TLFKhknv5<7E~nhW8atYo^r8K$=pQk#w1QAU!e@#3#HPMJRk9r zrg6MC>A=b^VsD2dEZG0bLS9Wwu17^cg@$E~Cf+4C(`6i+OaoGouZ#8W)qjxC+G!3F z0utiGRn;}SAh~M=g6oN|!%jXb4W&bS$ai_!Jk=m#KH&YEWWi9pGbh-%@Wk@UuP|}u zKE4B*cb`?coMH?xU;6Hr@&GB>?qm9OY38MCgZ`S=?gC8Wl*OtFX>D+4sbpK3adu4y z-{Lz_+X%1*eG?A1t+rgLr@~Bn+ePqeB{W~ryX?o;)9&5<(<1YJVbk+G8|df^US$DK zbK4LVkeQJDIC}AJhF{#>`Pz`mtWqQ+x4inU45jT!W7q}&Cmj~WXH4oZA#H)W?WLngkGQYx`d+H0Kjt?FgkKc%PyC4 z7TczEQDSNWAa>Q`6rI{Axc6JP^|Q(#lN2Cr;QzddDG|8j`n-AG+iw)e%LtF<*s2G< z*cAw`hwn~rY<*Gb0!bPVmJ==dZ6=o4-(9a+A)D2hUwH_}OtM$jli_8=u@4H3>ax}4 z;UVdkZqScBc?r0;wB!V5!#7>|-hJNbeddt;{ZFgJ@_7ruH%{ECxwn8}QNAr&Xj0$1 zG8%HBl762ZHtti4t%=p9nM(>FXi^^qGl0P_pqWQ~Yn-O&GB`9e8pNUlIXtRJM|t4L z{z1*PtfW4?Nk@`+a`o=lTfM-B8npG&HL865AW6Y6hM#cgL$-`Ct1UVM9;6Am6@xietG`Y%!UL*bg%sL}ie{2tL?hmW``xQKFAMJ~o`wirpUx}T&6Q8ueFsyn8L$$0Y*>;8uBw7lE)we}g2IyEDC)%hx=A4dm4#@Sd?ZWt{e zahr3RN+V66wU*QsWV=s)vtaX|!W|qZW};Ut4A|$|F&I`zGHtME14&benpib7ia-0I zIaTw%qNk4$nD}nl-`ba4ktIi7)m1fEHAlJB`f1*3@H>-F2$2^$)%9mvyCjHxwosMg z?ovqAB@z_XLmwm65l|B68OniRDp(K*Oe?WjY`=3R{+Brw;bnSAitd`Wr?2JyHZ`%n z?R$4G302&36?F+(o73)^@p8JSi15$%fOjFg&pG13zakf@dj>X)lpEihW5zWs3uc3T z<#kFYbAA;pD`c-q3x90!*8NEA=F;RjU zvoA);^<;haZI;p2fKmv?AlA?Dk{*^HSobQ7N)3ErL!> zR2H`VQ60)O32|+>{@wxo;QS;Juu^ASK2BEB6x1RVD6f0g=d zf9SsScnW>Kzs{Y_E$N~}BLz@9Hcs3VM_9Uma(whdtT(sycDAiq(tn-t(h6Z1;qpF1a+U(&Wv_g64r z`OA!lXa~nXeU91Tmi*4k8(b(6!my8kc)0K2ll_I4d*Ef%^0=yt*h6UlbMDb&YwYY$ z&?DxPx~a~*FZrY6wr=qE5Li#XpfIufm*WfO%lqWjSIuRvcEw+W4|$Iu!AZ-=KD-^A zxkIm4heOM=u-7VnHrJ$2*}KOd&KwWk&t|tdt^fG-jn4$SWB*xY35jpn*I<6jACOFCLz8?Nis$U7`VbJ2FCl zlx4u)F4q1^^Gv#Ml1tkOJ&G7>CK$T`&-H~R5#U%%SoTy3N)r*28%dc48lHBw(yW8r zFD2p2LBnMSQABQ&W@eOTw%dMkH#%0b#V~c?r{F5n#k8`dW-{+Zle=tOf3PwMo-;5?zj2NRg2xaqg}maVyiM?ay1wW)Rji74g2-VZApohk{`?JV4tq`R zH4QROG!#YziZ%|>sN6H4pfzEFD^73}Y4CKfqCv*_@lilHVz zac0L2XF`*uCs2DU2-^^^M`qG$UECsgTtn{6tNJUkU>x>8w0gu5gpMlK4Z(+HoMT!W zN~}+U&avryV5Y#qK{uUMs0fx&-#*Ly7N5I=T*W`r1x%Q(&wM&>fDd(;;6$-7LANm& zA9C-R%R6*@iMa}R2=|_WzO({S-mn5-VSI|kT+RDBZ^a3i^+xbj@Ov`{?1iXOYRiLb zGOdvB2>0&rT4h<7lB7txc!d_87UH>R@C21kp!%2q7$-6-^5`b`7Tn>jeu5@MLOX2Y zZkL?7$dvVkp^o9Pg4JMel^u-yb0FM|Qz1!fTL7LM<`D_Q)lM%dvS^7zwI_D_UZ*_= zZ9=>_Lw-Dys9ormJj776^_%LAnb%xISiPP?ctax*)#QfUpTl59&|;~W!~?SqjM~!I z%nAo5?w!?kmDW?s#ugUT(IJ+!z{yYEeN&W!Uj z8r$?L*A}_8bsH-nah=uHa!Brdm=M+wXD|Ucu$WcbN$9(nX!FZ1B}^RDv-4?Y!5$k- z`Dbq7RVolx!Qun9n^>^@O^sVuhK^6@Jf>1*hTXF)nqN5;cSF`gKKvH)9~IwTUW+1_ z2^@&7Q5M|qLr}yO;TPLJ=$(MKe>O=KlOD|0D*cp)z>D<`K!-^!&Q13vFxlVn4Vie( z05hchlk<*a%#}XbxoQjR*-&7+P5L9UBh%G%`Th^LUv^YF2X<7cN})d7;GFqH7pas& ztbPVEd@6Ijf;e9=qJ3z#d5n;<3j!w*fo7lC&%8A!6Fan= z?4Yzo1IUXyDG+_@Hk_>e+v2-D_lGZ$Y-A2rO*%-t{xu4)0#Nug2(k-Ok2Np3_a0AN zN@em*Br zNShV;VwIs`oimR3Chq~7YoFQyJ}yK&8Gq6!6ne&jUaD0gDvuY9vG~1A*ijHNo`0WW z9tZfbYGdKsfXD+qIn#D_+*fV-y6VYyi`zd;l^^NM0t_a(ADVy}vI;7jSoIPG>Md)J z^qW=_wC$pO6X0V^j%%|2bW29p)|bs!ZjjVp;*$7=D+?tp>#Z(_H2~4InadP3R zScB}b{_V5EGrMNJMaX$N=h{eJgmUzpelP$|iX?ke@~7s2;6WKD^4dk`YE@zSBTNl~ zh3wAh>9_g8ZxJ>=B;P@|WxIc9oS`^+r$nY~NNq7PORktgwaIlbF?;SHMYU$D3co2R zcqJKG{QRWbUcG_Dq)pHnK8G*-#U_99{j84t#9+1eRjE1$bM&y|0C>Sw@VT`I*NiYQ z-sRPu<7$HMj+*QPfFJgANnJ-zBSZU1x7Iw%teu?u{AZX{k4yr^pjAcbz{qzl%c)89 z-tr54Yi%BMT~Rm+Bj}s^J84Tit?p%ODH|RN8rgMVCQmk!CIQX#2F1i7&_oyGVjX0Z zP;KstU==O1wLZ_MmW2!EK0FAPq(=JKzq;R!{NQD0liyHt30y$_?tAth@yNcipPg!9 zEHY+L0rSvOs^)xKMvSCw3`bt-!e{Mtf@9CxG3uF*+eG#vBnAE6-{1*p7Gaazj=Vn9 z%X)AW)}gxdwxK5qbC+O=X$1 z@=L<5lsZVVQX3mTKZ;85M-`!ciHSqhFv_Kob%Ox7N~D@4ZB86A zCf;z{x+#!Z$&o9Th-Td7K6z}vVYb(uipma$PN%Z|Plc3;NyEv4xa?$X$4Y*a{&m~O z=Y1E5UXqmb6?Q-2O!6KDC~NAQvmP0!Lk0lm5f$jzwS$&2lTA#S@GQSwg_<8pyrB5&MKP{V*efgINUp=L%`^W(&`%GoL>RD;%fE>0jl8=^GCTSRe z`18{G?xAAn_W=sFE8Q9PKasO}cJ~^eBg&<`myjLG`06)AFK5R5_CAdE$1oJM< za~O!y{=^RfvtN{g@!c7HC-Hv+&Trms-iXoLA2o;Y554r9MW0?TKCwUG(boKjzUsG;%}+!=N<2~?hQM(wqYW)AOG(4vk(#eXz$`{qkP^P2yJNC5gwX9rYawDiEJM#NZE{Ts}yBD5ib=0u0>;pxlGjq58-3dlQ5KY`r(O#k`?+kptQQ zRr~qr0k*fNdnXZ4F?=ImWe`)<*ca^6=#Xjp)F$8P5#>b?odhVnQ71)flxuu$Ff5 z)46AfNzHK75#C4N))%%+tG>O3VsjaZRXT7S+1NrA8V4N$60e|TycodYvrYDSruf(> zO;*+RvkuCzD6lQ+D7|PDuqwNURv3K@teeSoW)#Osx}~vcB`*| zR3h#oILL+JhO_BqFqDkN2+6YYPGKT*^P+dhEtt;=yRt8mp=hBSPkSL#V+zy%jU`#` zH<#d;IJ{Xz2$c;>l3VEHN|HzehmwEsF1oAeY+PC2@Je(%I6@J|kcXW?R}sw8)p;~P z>Z2g(xB;wyW|Sw^fMGt)v_^+ZdJSKS3>~M3tO3bSIdgClkaJ+#-_!03J2wh$kae-C z66=4b_%%&hima2d^z!)F$1!^6+L#GDqiGgWW*tPg9w=y;R;|Jdzn{k3d9B?XM=R5g zc?G0dO;bzM1TptR!lIKJtJEL`I^P2Ht;Kzvu!)Xxb`%Clc6*)(FXhemF8ihN6VpJrEEVRty@~ zr1*6{8*r#6`9rx?66xtKTL+R#LO^%?p5M~jmuY9;V>>3V8T*yNV06}i0CR>4choR~ ztHcs?EQaf}wtkDrC9P~asfT$T*fB8cDj*X;5>p(kI{i%qo=t6C$|Up&ePPKii6iJB zk6ili>b6|!3tOGRze5F1T6fl&*=4+k0{q|Q(20mMP<`t?0Ynza(^&)_^-tjEW4v>=eJQ3B_a z?~EHiRt#6R5+Z8^k-b~k>XP(4S87F-<*0xPU6<$juNvTvqMM5HWu#Al=N)>N2e1(G z8Dc&1H^|z)13%-3gpt-&e)|^=3$kBa#0@4^Qge59sf&&T#T1_Eq~RVnsbrvm3bGzZ zH^qBwMrGSOa+c7HVv!+}?&1L2aHj!2v?LV+;~C5$i{*i?G_-8wCBa82t@z%G;h}!a>b(--?0^LN2EPgGOH>_M=3{ zI4m&{+?FG#t@2{SW&N{Gh=i)Qp0Yo$NN2%!lT3c^5&^bUplkr-LGWKX7CsnX; zN^SSJsQsT!81wm!7zrnh_5af~mNJhQL+n%*<{KO0x?H^eF7;o)2`rx*Xw=z)cp)yC zu&<|XVHXpwyeC0{qn#&QPPsK~nc^g27HHIDnO~C+brWo;R`ZX@os6cX`<|34YOI== z$c;+|AfyhGP)yR0dI4)XqSEkX3X=dD%)+mU-x7;%PWjg}uYDPPIQy1fc7T!dB@Zla zkgA5DmUk|xRk0^)wBq~zivhxHDP2bDwUq`>9LscvDGd$$NvcRY^PuWn8PKRG<|@eeQi7xKD~b^mMMom@r%SkD5Ew%_QeiPJ$YMT5Nfhzgy2u+f zP7v_`6rMX@M&+Mh$NSjGJAaT2d~RQDh329c{^#E4DMJ3-`{cf*Tn}GZZGTMQ<;pR= zR9#&@oP&GfY*4Fi7jT#T(=`(0fYyIC;MGuxP_A$6E8Q|KuT_S>)H!pk@B?eBC8^yi z@@n&J;D}WgwazNUW0N6yZp)P-9yz=69vBfgIbwU8<=$4OdIGeaYKsu~ zEK(NrORysnvdnDN{}M+QOfgp0Hts9Ui}%&E;g5qT$TgK`RQAqbX+q?V*3&^XTO(P3 z?LV}y0jtH(BiGpKP9GK9*65vpIe_7a`?0j47KO2e_sfxXihkTKWrPceZn)}M=`rjJ z_y4L=sJ$r!=j@ip^W)h8f$?uAN0H?yWS=xKP_r>5nH>!%hz)XMyTAX{qKzYW_Fl zEFc0zTAO=+H20pc{hI%JER{#Ds#o5&5+-woAbIt_R@Gq2il6))w07LON+Rk_Mbe72 zKMJJI)E3Lr7PJbhI>Umxmsi@+bZK8_=n4b7Uu)V4=bTh&iMUyHUDoCM&`Zfn7PWyG zb4KiVte0qf2Ov@=87Rno@8X)$==l5K#523}U9J~l8GI4;o4jQg-0X>1Ox44>+J8ND zjwR}3HgErYPD7#u$S2>HJJ#QHzLxx!zh)02VoXQEcyQv!fQZHTP+MtZpK zOAr54h&mW5sa`{C2e}WYP9d~gfLE8q(-L80`A5<5MA=OuTi%Q-P$$-2MW*ex{|I+= zMuEcJu+x9S-Dt}!{@=jbKCI@(EqB%NO&~`}sJgZk@^OdwmTw~geg0h8LuU6C)V5Q4 zWG>LPn}TaHmT$@F-H6kv6CuWh=3ohJt0zr_JUWvhdaT{~J$PEfqwB!E_^bc_iFMP% z+ph;Sdp!WF9wlOIuE)U0z`yAduhH-aR#$gnJ=Xcgo~tHE-UsNO(w1laQJP#}f_pNI zkT+I)^4@`?P20k?^;>?_VSg7`ZIcVQ+C0k^ULMm#z+=Cu*>#ZU#4WRMhlo3 zrzMyo-l4t&gl0WP{0-Bpl*<0>#9fUHXP@-GmpX@liV8mb6Yu()46wksq-Hd?Ak9Vc zc6J78HCGMz2`!J2elFDxDTD9;?l+Q=gAwDf9bXNXp0N}*&4#&PX0**8n|gCYb9OF~ zzzZA>%|P%#Eyb&=yl&Xa+A$x0qt_$f*iYjBYObtJId8B4|7;_!+&@QA!6qesZ3xsu zARg*jwc7blX4O+Mx_7}Gohz*^gakptL)HB(2;Jrf?sc>=+1D(p3%!t+0!hnArOPwd z|0!o167|i&B!QlYdQ7Up*CA>K;>S`!NR@TNx0=hXiYP& z-`=ivlf~Xch#}!$gdG~^Qnk|2NQE^4P-u8V@M{pPkUh=WWHfk^KP{xc*YkGQ+$c*2 zNMWt04;IyVrCj{Yj`q|k%!Hqmf!KU(lo20EE+Kp;@WRbS#46s39~?t(Nv1~9)J!d? z;HVRc*G_xe@tN2Bag8#eou0jUrLNoz!*4%o)2a_2y>d)W)&5d6(y+sTl4{kODI&;j z%Ai$9p3JXIuw|r7gj8+9fyx>yhlBfBzNSr+t%)nUwoAd48$Z)&5t?;5xpQK|YA52R zf@M|RiDzf41|P#Ak8tUs$Q-({LPAW-6X50rWq=(N6KB)mLW7S!Y)+K;9ol7Gzm@O+ ziLSI+1r4scp(d(1ARrF;(&8d&5wa0iA#F%Kwx_02;lvoo{wJUE4T%{}y7x8p7BAA7 z!MgsNF^}nRKm@d(Zhh3h>&h!m^(jq~kMmN!Va<}9O!^{C+`M$J23IcOoXXh{KjXaf z8uE+iIoX&egvUov`!E4j`7Hi$?HF90z&G zpFI1HFLrkVzo94CGvCZyb0+(dW?un*s@cDP+d`uDSgV zvYIHiU_HKhsk{Nbwm!G5;y-7XTcY*|zE~{2t;?_O-;fc>!~kus5m7BDdQ;BRPfswVNS*n7oIbd-AbK1%|RkHS}nk#MR_) zd^d9I)c>Fu6T|*z#yaApZnGZQj>B&tEamsQx9ycu)Is4#-`D}VI^Qt5?xgO?h5TI! zLbCqsq5ic}r^Fa-7}pnt)+*^yckZ;9gsZj^RghRQ{epy(!Bhyv099&iyE+TYruSHj z3yxB5ooN9UPeI*ydZpCr7FUD^`~7g9>c3mTg zd*|a>7t*J`2dq+s8-BkSQ?Qsr2&p6{UMjlr_V7E*M1Dc{~5lhKBsR*(As{ZcrEO7#~>3f;aUgh zz*9UG27}zE1*p(Hw9!M@=3p4FhWHcc_}C+~aZ?%gG`Y%GZ@e=clId$@n0rPUUk zIu$^Xj97_lyG`>7mMVQZ+H`#PtuoorxEy*4QV~(N=J#M0{SaKx!HA-xi+P+0HReOj zA$!&&Ii_RMn|dK`yw}Z<;qaHo;Av)cKbJj;j(iBC#V~0*j$w%&nQ9juaA=^tbC(JVeaeAj}j3?~t`eB}8omAdPyecWrSdgjTYlbQ9a(yYoV zNzr>DVJVD0yEeh5g3i!v8zTcOp1vumCGCE#>V#$WyqX4`16%XEykXjR;Msm=h35|` z|AVuPIk3q&ZXFs=4i066@(|7t%N?5TL?C^6w0xxvgz9c2m;Yo3)m(Mi!h>$QcczSa zBZqFW(I&7s!$Kn*{wGu_g!ej`7emzX1hg5+6Y$OAR_Aw>+APpudq2^()Em+xkJYbI+9AzRHWHFt#(i#*>CZh#ml+Ctg*yVJ-&P?L4q%c7OU}Ls z(WnMl4)=-1J!!Rpva6qM66Km}{JutN5ASeSP{E0ibb`B>O}vFYfh64*`nfNj&^~Cp)w1kwd{hP(UiF}5{25nR( zBXrHCMLeJK2Pbgn>HQi1)>@+|LRo0dyH?@LCH7l~Zh~HHcjJz28=+`LtX+VmkP0L5 zGzn}!N%4Br;Y5!sR4`O`!^gqfTjy{qwx|o)+7#1Qvo8nD>rJ`^z%nGcHuW~B{7pms zF}g!^z(=KyT$0=ly%?PgEIIH3qqmnyKfqjCpnqfNo~z#h*Xfu6CY%&g>@Ljj96;S! zMl_ZTnJdNFR?VO3$+hXu^Rp9`z)%L{R&nIA2Ykr1H#2K;oEm1GyyNK8!Uny|y?3{Uw`!x|eitF+!cK z@#!dLAfK3$w1yjMcP7^=WWnUy)#n|6B|dWR8d;Z$gVeqRJKjNaj4XY17VdefMLRBR zM(ioF#}uJtYSuvVbaEbNwZs=yCI2n9y0`FiG}Km%yx^8YP4`EOoel>Ory8wkDtAw= z3lhrlBzs}y$YY*7Rb&mdCwdAe7=If0^J($b_VoBY=8kyK5Ca_k6^VVzNTw|Vk0gSS zlN8cQBrVR$qeUw!IK2o+Rxhb(!y{_J4V+gnbMX+VPlC(v z{RNwtTijG<_MDUqJ^?2hGK+CTz}xoYcT6;)X;a$>MJ90ME9HNAu;C%f8`QdIKxE+i zWv`utPYT;t+G+oC@8#RNGa@#!PPk8P$8j9&5i+M z5(G>W1~zf=xn`kCmCC~pDKdXSa41JQp03SFyubi>!ha7XVF#tiS!EMTdR(v9i zlJSTx>W+VpdO4xflEXH_aU5ZAM`cz{JOM}yGAG~ZIMp=aHXe)>ONf~vHiU&;`62(lBG5R7vE1-{aQ=5hfC27Pm{-UNT;QPJ0B=WF!oUdV(q@DRvTOaWqAWUIZ~UEgh=>}v=1`G6t&$dxc&sH zLAL~H9x3HsS#$tJD)x(Pk305n+R@8U;w*E@2d$1&;qOMHjs;XhO>TQi`JE^hI|S0^ zcj?F3qUDxx#Dm5Gxc<^GDQ#Ki%dn(ntuMf8%$GQfnF8mR&+U?Hm>~xWT@g6wfwwK! zoUM>ISc2-k_qd`4D8g)|r@l_an50odac=Rb=l|*@`#1ZlyzA2(P96mD#)Byg%^cxj z_bX<4gQrOC`?7st3Da6@Fu;ZmBf@n18_u6%(tww(8WsVh-=4M!c>(|u#q~;rWGuG4k+c-dLF1{sxZb_K;+a%sMbvJ5YuyV@oRH8e8rRjVYTzE zF2t)zLM`yajvWDNZp29yo@`aQyhP>s!VaovZSW9xEcy_8nK_J{JZ3GwUE}x}d^+M^ zwrdML7OCbPk?cxxQiDzWwPNKmNl!y1-5H?PbWW@i3Dern0=^!j&lo;Zk8;UYJ|q*X zr3ZJdKy0}}oB$Nl8;?7;S6U>8NJCGSt%Deo3fEL(kx9ZYzlFrFJW)H3xurp2c19Iq=@3t=?j8LyiIO2!UWhCq3Yd zQBMue9{?2uMqEThaIOE3emVjiFPjb7Wt~3~f%TIUZdr!kvkiL!4>v~?pONf<%h0d^ zr}!`ERr*664kqW?rxF9jFxLuD^Uw}*HM1;y;RviuU`V{b01E}a5`W>Sa1J(rd#Ih6 z>_H6r)!bCL2-Gql)C2{>*n4?z1EbNs3MZ74^hpZVGYqk#`qGRUzey3gW<)T{h2U12 z7;3!S85FmqF3JbzV(sKj#uH08Fr)AFKKeJLDi{BryHEwnG0Ryv8VJC@)Bb|uAR`#_ zn-0oA$HRlzZqK2%#O@y~n?huS6e$SHqkd5|pvHgwf`pcakoOdD7vGdEtkK|;3*1q5=|32^Acas!Q%g;6r{;xo zY>BG3?rY~EnsIB;>1VKi{shiT1ZUZQ#HN;>^G5fLkPnLFT)ZVI?arXVz{0jH^S66! zg0kE`F`u1CPOYRbVou*T(SH=viKv)1HUOX`*_gK5)OPKiC}%i~{WSrkYUQu&y`)CA{*ENcJ$PfKj8}t0=>( z1&oddloB@0igZ7S$RSf6 z3086Qj}dVA$H%p}-x~_Z%jDwG)0{!jUtTV-CS1l!^LRPz@_Bnuo&N)xvT2F#JKS+g z?cT-+HCB8ky?jEL=9G*e2k+J9Z^H&;!JT|Z{HCvOWeHaCo1eHpm#Lffk7YVO_HWCS zvSd7E%yK`$Q+07z6rqny#nYtf`IihL^Z1h5{MWHcgtVS_J$#taOAyMSt{7uIbqoYA z7Ikkd-i!!rx>~(Ytnr%~KX_}MAJG@rgl*x))rf*`3z?FZ#;EM`ig`y(Jn>Ul@KL*u zfK4?K)H}tYS>dR+3foYRT4rLHz90`ICh#hO3-I;z*rp@>UOW-MXobO3zpg*dD&;vE znzA2&LYi^@#@i1{6J{$EglQiqePlaxXZS(3mG=75nI5Ym!T_UQmYRF>3DP{(DR2?M0AR(MX$fR ze|JUpOfiN;_WqsgJ$4=#Yc%AxLYA|DcPj?UP}nTbH4&%*hA&e zw<>%@$#izx2$53y(tB7N$@e>td3R^JwVT}iv}q@sT@y>Hj>iD7f+#O$jm9LWqd+sa z+FT!H#o8{fkQ-m~71PBf;SGzX7`w<3QQ&W>pI=vbYEIqlIa-|j2N+6&KYZ-i z0$$SPwxV2JXghew6PGiUy@x9JiDF>mpX(We65zMV(ym1Zjs`t?VV#>GsPiwF40@yU z7M$v#9SJra(DQQpqD1q+$CTGD(Q_^W6JUk>&9DE`L&G)gd4rNe{YRI-J==FDTN}ZT zN{n{Kl~fP{Z$iVBgrX(t7Q7qU%|1;)(Q10n>dNYU?40b336=E-L5*~WZVHD;S8K|uC3|pk->3S;qlkK zh_(yXyw_#pt#$y#xt+4+> zviB34WDKaYj=QI_kM`YII&hUUhA!9Zd-vBN)r8)=g1-Ule};U_$uS_{ya zQZs_Fj$U!;Q9Tv$UAijPQe9{muD%f!0k`w*@fX{u{_El0NZpa9dThcX_vbogOQN`g zM90z=jjEa}%a9 zm(G*QQBr+QyF^l4ABvoCw`Qy#inuVp5|JD~J(W3028yc#cSw5NW8&Z-_w(I4mtQrB!?*5f0& zUIjcDU8pmKWb0zIbyI-pyc}9*c2}!&o(xW6-XF2%QRsxPdEh$CT>_G^Z0Y}h$XF+d zP<$Kui<-Jrx2|6!Wt(v``@YVyg|I}3b2M3Xp{Mqw7t7oH@>;M4S#?ooS}sDu!UHz+ z62YAlR`)`(UV<*^YTLAAki+pY!(VW*AR1|uozxk219Is0-N3yyokae4rx?rJhbd9w zC$!x*dl4;A|9Gb;U}{&GsBne82GPiGc$jFyZiCh>ffXRjSU%0;Tq=hZ;$O1Tx+7xw zc8%-i{Z>Li{O`Jf*V5$hYJS4ieu2KL8oByZ)6|rXS8p{j{f2Agv2Ug{B%5H|+$R0X z<#lW1#p?w{_5liXyGdiZ;BHds@*}crjYsD4eM3{VW?!x#)uf2tF&o*gcmBgTWdZjO zU@if^#~4$D?sYxCDN3S;y$IG*Z>gJyCQ(do)|c%YQ8TUz^R(z^vNrQ2$?2 zs~22o<3b!5U;^&9oyyQ)toaOJxrqkA+l&hA**$jq0m8u_oEi3(yg!oHrXpQjz~Is= zCg}O20Bs}S6k>{eiTv|Oh=>Vva|i-FhRzk0)hhW%9dcCt3adfk8Ss+x`g1z1AIEuB zp9OS{c#%QwCPi;*m5TeCS_b8vB~WVrjA!5puZC_aiwUqHaf&L2kcDFO;2@62hKd;i zI}FtZ=upZq`O+B(A>;FsQ(RHS=L-?Tt>&r~s|f~#N+Ag!%$63jw{SUh}O*$94T+f4gOK2~C*%Qdex6W%dsd&kI#sBrazg<=TUH2tAu@Z*c zjs@MmIkxCPJ~D0LXV8B0m*hOiyVxbwx;(0=Ns9djZ^c6XIdpgY@TUthsSAO11Bc2& z#B}C^o@5Q?7O(|(^kHX||4^f$Uym>DlSQp(N?;U_y2Ma+2)?RKNC%i3NRJ9`Sg0{- z+LK1Al803~w0mX;A92OOEb;OGmKL941@)h$Tanw;HI%Vuj2@&J{6^+FS7yY#g^#*X z-ZJuQB(5(QM@knNdoPh{>mGm@7l;PZMN8o4l|a#k7qVy5kyR&b5P2}B^29?0K{hMZ zS28v`mgD}#hrNXFIK2y_dXNhE(Fkw(TCdKlOjxs>_9$L&Po5n~wR_AJ`5a}>W@CXI z4}W^0PIs<#Op55B4Nc?$GslDqMnS@H|)4VMYF#0(io^i)Bsa!ypgL z9Mf+M_wczgV6e9R8s-O{%hl&=$rE0DUtQqbh+cDih|f9X!310 z@=v2Ab9@j|_=c;Uc+~J-Wiql3p2)hERF*{Xv7EM6rT6U8bVx*D{Grno@?9Wa z_XY)P7^}%qW)-Bhy`o^H z_1u48*=t5rN0T;z4#1RH9^ipk`0k7)E%~B}XWiT8rCps7Aw)P;a==5Zjqp910Nwiy z#+gdBHRDP7NpayC=yey$If(g&>5=$$p5ov?EOoJLSCI6O2? z6FjJJ&i*@UF`AO*6ot5)F?NS}I_6MDlnn+3ldmtWV)__U=qvwMZM_Ps1M5F21}~P4 z9@S36&{AAU+aG&4I)NGVR2dz|YWuOK{MGL?RS?pF#^pM}3w)i=$STh!&)OcK6kc-~ zfjX?WH~6Zd)5Blt8t+r~k5!6tOCD_XS>+Lr#4<){>i+nQ8|Qh6WguY}%5a34a`-kk zkg>1xXfkh`ehXQE#!$JBDMwaHa}ZOx3L&29E?GYGcN7L~eH!@OCo>F*t`TmQtzl0( zF@j|yl6FFV_TQF*9}XC)jV;>ulntS9DlXaa5oN%GH!Zlv2EGFt(vc?G$Mn3+q_165kE8^@#J}h z81`C$u2N5&;s~bL$Xv1|`BdWR*epoVtutFSmltZsFpt{~?o!q_qr*TbSti50mP95H zI_)nj47No47O4F11J;2I)V#T$2J)x4Z{Hb+Br&;E@+m$h1DJ?9!lcV?RqJ`ZOs_l3CkT(? zcC5^$Ku4Ped4jjP+%627XmR(K?4!#tP^_Z3+TCnKfTeVP2i~b*V{{T}dUJ&;DlFsF z_KekesauqbzZ~aiqbAX%xW_JwzgNZL)KEvsvfkEIj3rev$D27Kw{5dO3d#Bmg7*2& zy3F)%@rMH$>hPK|)9ucA^tUMlrVEBiB1}Gh7_@ zJ~cRZ%L05&@4;Xht)Kir%3zOT*nYxKxq>gNnT8k$!Dd$p-^#k_-=A53LmfKmnctAW0FgFI3H=XqzL~utFIIS zI3c&2Day9*%i!!Eq5VHeN7NcGEV7k;$&j}OEPD!q^f4sJCdFbR2#i-bjgEqG<4O-_ zC=py`KB{`ccJ`p-t{@7U#{)^aogyH7AV_P&&HX-T*<-&8kw@pb7&q^oO1 z@-rpEHn6*onixutrz1x8myGFxxC++kCXmBK#slya-)_8pH5gpxQ3d)aqJp7LD`yBu z`WC>WetPId-CVi)r6tMOAudFypuzx1TS2dx*c6gggO=)yCuj#mno{z@zO47`gpRi0 zI!3A{Zo4w-ASh}jjA-k`(gki}*_dP5*7dPBjigP)NP+HTfSu6bl?}nEESsfO^l)Wa z>)66(nt{&nu}6_ti5r>I(9l-Ut?%7jZlZC@{)Bz)a`>v7SpunXpyQmG{UCjzbz{c& z6bJAb3bt$~ETbY@4L-)P`-r7iRH?rTL8g-FqU-Hrkr&+k&EM>5^g#8={I$wgbb!*klDC3uW}Yu?-FAJ z`SNG5#+u0SRySHLp-C|fpobY>Ap2?jSyBO6R;kQzIcfFo|0ic-oW zaiMA2ll-S?p?FRi7kX=fKpSCzVPv0%gq8Zse7qhTFos9orUrVRz(y1@e!Abd3ug)i zq^s@|8~a7oXf)ZRKCMO+-inH9T?3AaM^8Is2YxJcZoKV7t8y_vw7<;VI~&;G?;KR z?_u9A!~E*566ms@EE+BewuBVtsT5gNe52f) zY;g8mjpJR%)bFwsPixIZdEWQ^ACJ_<6<1!Vhg@En;=oi(vSV;l%T&`X5O5-8P9!+z zl%pM6@`|ZBdK+g2D8zt;&4e24M=2I|X?a;o6HThnyBS+!C~{?tqUugXObbi^`C3p0 z@Ia-?0p<}Zk_Rum0EOMhE=sB9PL|4+Ts=)F_6c#&Ogbn$FcRPE#9;TXMnGJ3SJm|X zVObH_JeQIwSb|6LCjgH=f8Hj$UI8ZpQ#l_EG$cwYJ@d(JBK0Txn@TMjuJ{e#u|M}c zzJlShJ9`J>`rm^(tJqV{JJxlO*+p5~gh$oS4O*DHFBluunY5J)`I*2`vs8#`3gY{h6j!m**&^vooK>#>=j4$-fwU1T09P1-?bIbc;wpU%F1LUJR} z(N6kdh}~h42PZ+#zzo&J&&>5mA(=7n`9P&qzxh!}Lz4Z35VL%)(ga7(2i75Jeno55 zY=aWe8CsJ979L{=ixjTd&#!t?;mn;|nRdPdvhh*f_2TMtnPqmK&eN{mg4&A4m8)Xb z^1Y!uPYEsWi?W+JS`m)NnhneA%`(N%F&dQ_J<=f+uw~p)_Ka0?%ECDA+RCPYaW%GL zOBA!&2W>cc6z;E0s`%J+oD3OL3Dq6`Dg-vtH;siU{2LUN?s^X)GbV?63Zqc!F>LvF zZf#8kipohbhmR>bZ&PCDpIAeRF;t(4 zd7AD>`3dNBzg7|lN~Z5_PViLZ@|u>j23t~Cs)2&h_d-`Na$V~X?VPnS_1~9v&dbS+ zQt4@!;u$b{O?d?i2IAXk)|C`N8uk7vTgkWu=JkZ~L{)KSS(->_EJ+!~CbqulQ5c&^ zN$axJC0%XCCOe}4(4;OanuB1!{L9n7yl#{dDgi|9euAMF*LnYoCUtJ_Rih5sS{I4w zGj{`ivd8wI(7spN0Pql{b^ds(>p*WcH*M&2H|sFxq%;LIbl5hg?e&jX2oL1Qy zZY2Ek>W?4;kE5VoxFj+kdQ~ygeDlV9^;#|I@+SZCvJevgQEm-z(@Rlq2>y7F&UON7 zjQ|u^@Nk40a8x4lk7<6nC8yMidPtMhoC{wUK1wDKAYSy`Pc$7t z_X@D_|LjHv>nXn6jlFIRY=-=aJ4R(eeOk*)^rc#lfOjLwOrN8v58al_<806NmC~|& zJQQ~n8#cukB6q&vC&USyoRy9o!%eU-E*t2wIaEY>x{>wyf(LV7Wa~g}AKhx1Rgmjb zbzeW&4_y4@-R1jj3tVEjNtX9z2jY44#-G7&w#06K5D@9z<_SL{C@&cC+~z^nz+Q;2 zNj;025?sEXyFG`{-8_#m$lcD5MFGw1kTw>|9KKY^$U%$|`^ux4A-M{Y*Leb#JkqW) zj<;T`vGR625&Ao5%F#tEa;Ywj2uS4&L3J)1ZVl;QlK077A=6co%}m2Q7v~+UpMfxD z&RRw@0yeXpVpB?3DpkOjWvfqAgWTYuLa_@`!T|=@XzpsjX~b6aE8gX!WxIH6hI9}% zizDbA77pJ!QAIY~k%_u_m4SJ8h^FFaxg?SP7WF|_Toz{Kqh6W=JRD;JYqlA4%K2eB zB>tLTZtc6R_E%W))T~KfW96Uipf_P{iX`BS^+5HVfrH={;E|B`E&de`MoYFa90uDo zn$L6ssP{oiR?dc|Mp<~8`USNFvPpc)f1S{ff1FSyR^_lg>q$>WEYVLMpeA!Mwp5C*spD+ z*%PHVryI|iN3%-OHoV=U1=m`9lA;+4mchoE-Rau0k#+|%G(M(@q10<*)ZI!|Da{dd z6Wk}+73yoeycDx*px!2R%$eg zDwfGr&QAsr7XaM^f?bGQlMcPo4wWzaz$*Sa>QK=l zjKP_(Grn~EZ7~{ysn}YqiuW{C-*q-?U6)^N^TqB%^M#n$EgwiUE530C76)X{yYs0& z0WuqY&@}WVWM*DRIEmFieIApeibBcu=$QTTcoHDc;zQ^dswD3tj4b#-HZ z#Ao{){F3PP=UeTI&&A6JW5(V2S&~Cli#D1f1O;=U9ZQ!&Rq+1JCxqhUzZ|I079v9% zaF^EA@=?qsZg_2vwQxvD2XNHZ)1w-1ybnHHBlh_`dMw4!CVp zFAf`X{Wg<^(NqJ*lmG2=YwvmsI(xI`I}fUAd`$l&p&1KGoTd}2H^X=Svhy-6#7bI6 zalbx{Q#<>1P=Rwf({qC=E9Vo4do==+XFBUv)A*R7p{cCgIUDiNTmji;AL`9|>&^)Gl30ad!A8z?MZ!MA4JomB>BP*xicY0R>4Sy^2)lqxJ5csOfb~~mvCQ2ug z=cDEsi@Feg?fN!8z_2iqvRsL*<`pN6#6#EX>J+((c!Td*eApXC>p?XZ^3zd&gFuQ` zysLB%WuYIW!kwLX{EI$%kJno=37g(LRGk%!fFYmUjIQWw7Dl{P8xi|8KZwJ+-oM3B z2wkZKkZ7d^{n7@%{nIne>qfUJlHy``AsbB9UvBp?CL(k)EatvZ>4*=38AILR&P`}s zfD0)IPjpUTz)TWy>6MYo-M2(>{AVSF3nBswlB$WpA@T}kCL z2u~^A7c~TxL8Vtpt`aQcszJ3mOBaxb=O$f4KIuTqo?oMvf~ZE-a8$%0$qL{w!J`)m z{CFt_Df}ePe(GoJ&tY!KN(NU}14PGnDv1c7Fa%3?*(Jc9zz&d3beffW zM+{M^KPId3Uz4>-0Vq2l%9zkYWTR0=;GTTL7(P@RWGJHzw~2^7XCoaWM;?EW*5^3*Y@ zmI^0bw9FzI0>~>+rqaigL!dZ8f8j|FkU|GA8bT$Yf_#M6$a{dC2Ztq7!o`vX*8y>5 zbv<(ki%monso91ySuh9dT?#*YrA=dzcDQ%Zi^ARrq3IDnD9;orugSIDS&($g$swXVC?96rDiL~xXz({MnW`B6q$&pH!Lrc zlFR@`%YS&(YJv*s0+?^*O{LIRSC;G2u0H|ByRWN(>@d7^7bb+%Sue|q9jEzW@1KQa z%V2YH^Jjprk6jibmVzMeyAeiYm!zm1%a=Zw=(8u$UoJBObr@qkPj!`%Xl4vdyp5=p zxC-U++|-Y%hzP@B%uoamwPRUO+3ERU7cJJVi<67R5Nkmxf659ov!-)KFMlc!gkjgT zWKFfRUVQz{6?%m5T@n&A96YLc;C?TT?-S^uWwJy$%#7K3WY`Ulc%>8z*aZjv-C-R^ z^X0z3C)5;fl$4IX3uA!;dt_3jpgwCMl1Lf6sdLD#<|L3`uMC=p*86{3ul-~ae|F6D z&`xhuP*Vs9b0tSu+QsM>7)2(f?fTqt!Z9{PZ@+7a4SaOP^fpn$$T|1M-$k3wnMf*1_RDXb1ni<87-_8F8 zyf!#szsWQW6-}M+Me5csKUp|(u)M5tKU{py zP`nthGdUjVg`(wFoaUB*TSp<<;)Hn%Uk$T~n2pP?vgTejn$dLTLqNxe59MXHe$FfG z19vI!&1pzc4<`JrEY7p`65i|5sEsBkt0Ng|nVK_4CX z&>E#lXZpLdYjPd%$SK?{_0kf}Ni1i|h4PM{=O_#pPB~F?e~%UtEHbvXq_z*hT&m@o z)W$84U8!2vA0j}#8#hmQnm62ozM&C0O8WX^ARMEBF2asCgI268^`p+!_`{YjRdo&n zQd$1@ir}E^HwW5F`MckhqFSP>(A4AMPwMv8+b5nJ1}-HyL=I)Ilh0ieZj!{U+A=4Bz}B6y3A@85qx zoqTp?W0ObBUyXxB)Z|9LQxwGgz)OassOezr`X0p{d7vFb4lc1zNYG2uy!0Y<-6h|z;^X>Ga zcx|P-?!giHpi?Ntin|t(yY{9^oCPjcqLvLpeWS@}0IdHpVB(Uf2&ZP=T2qTA3-n(Y zDIq4fx42pp$@x-eSJNoa^q}8($h5%AQ6PcFqi=HM$)C3ClnSf- z;)WN|zc0+KlRZvd@@j=S(-?oLlIEMNs$YQUsiZ%7=fJwdJx7YB^#6! zM*=m`4DALPn(#sC6V_J0JV$)iFQlaG(y!-MRJMm0RVhkn**Phl@dc#JD-+=c^f7O; zXbBDKqXbN?j^0uB$qqs{#~jVQR0_)e^V1DN=3sM`Ts(kUpo zfe}2su@+V5&I<6`+PXo8n#TmcO9TW&?=VYg=p3Tg<(ZAC1gAE~vP}A6q+mL*!$D?> z%1)C#7+6D8*+{tGp;g5?nKErn#h|d|fTBU09}HRt3#xv6x89RcZKx>_sG=|l2L)Aj zzo2T%Z3g)-m%P?4b4k%%_4{I8*iGEA+6T{f9XR5mObC;TsN}c>)9BH_{r4eJS4b^bQuFRUwdbma|OkGk$?^oUdGG;9kP#xr)A6GwTN@D11 znu}&AM5C?Pi%>^vF?Cdggu+S@mSC;;knt*tPwz)?(z6zyMgOp*DDQe{wRcPOltF75 z$`G|j*ih$Z`qB>ApWrhk*fAh2@Ag@b)-LVYO z{occPw3JyY|TAsVhUVg*;3A=X~@DI0Oi4#JA1^-+=9du66OM!+=7O>&7X@Z`<* z6gX~S%YxwZSlQ1++%YLUi$lIDiw!rgqY~Q`S6%A`zVKu`H7`^&*q+hjfxmla_73JC zLxzl~It&3;Jh=W~^ZFw2z9GHr(%UrJ1leP;f^Q2s>34n(8gSP}Y6>SG!j1Hbg~xu% zSw>i#2TFUOF8>_{zfp=<5dX^vj1%XVo-i|PG(7r2O7RK^#XCN{n!t+Ban@`vcDiA{ zx7OGtpHpT?KrD$+{S*}M^JvZ8KCnL9-YmuL6ip!?Oy}nVv~b(4S7)KngQwSEPB=&Q zMif&y=*$WS5IQ?QHo&*`oucGr1VxlBIP$hTE*-tffvXLZ49-VszxnUIbd@M}2w8*7 zrn_qEi->X}ptY*LcCKg-t5=bZH*Da=Snb|Qr<5_YPP}|4F0X=95B?bT6Ef(SdJz?B z-ep&@=~dL5#{)?>40CxdPxg($7>XKofMYFYam&0UT(+7{n8!W82Jl*6&nn`$ z_-5$4fX-yp*k75|Uk!MDH}ERwnF9VBEt)e+Eu^V?G9M4$`Mj6sdIr|_Rsf~ za{>-ykza0h;+69ib&H4srQeO$==8@GlFmQxx;*m2WsD>+wv~HFJ%}lFTkImPaF~sF z3+Ig7xLa{@?$7CSEH*eO6mLQJ0_-*(=`9S{VaC~2E(dI@Pg`f}UvVyu{pN>nRJgYK8nKG~@OmAC*J zN5h~a{MgS6Wb2_P{Fy|(ig2~GYdzZE=3@<-=jCy8!nm+PxS<2J&ue-^{5=pCz`b(7 z{0IJrTB>j2iG5T_J%mfI^x{H)-UG1NML7P;ufi%>|BGKG6U^gscaruINenUpOMAVgdOo<)r@kbb4{J>u58X>i_VoLk4PZ zI&8g1V=zCX6wory1}KHiPeA+wKI^$5K*X;*M(wN5Enq^OO^`~8 z3wZ&~gFQK_Z<^&5c|xZ^x6FJ_QuSKvR+zx7^pEyFJenrromK>R>b5BBjE=+WV#6~$dg2s&9vLAQjQK@D;n`t5}or-u|g4si%Zh+EU=i(ApO!z%R5+OOG;NC?`@6V3fibW$5gHse8Oe4R37Y(&>?gj?k z&p(z~iuN*TJ}KQS;`#J{@vp1o9Ivv?{d)nF@dsqz$<`T-&t=lMHHwmqEb5QXoE8tR zcUTeL?|Z5dE6+YA-rqN6w2Jn*CLpkjwA%1g#|8j7h_6oA8_w!kX6#r{FALEu@ZK!uV%)9!2NS>ZB~lcQR7`bw=8 zQlyT5vhcn2M|l1@CpB6A*XFc#B8^-qC+uddemagg64Cyg0vH62@w%zj6Ss-|3QzKg z9KJu#bkATe*3e%s*mZA)gugoHnnyL%gI$ji(sy0qXRRWqV&6+cmfmCgh*!1WCLn4} zz7jn`A{I{P-yG@EVpm2kA3-z)Muo88l{R#LK#J*r6>0-U{|pXASRr;c4NY~S38PpM znXTgtZ2`1vXgZ=)JJ_qrD2T)M{bWBdR3N!P1fm+<>%3McL&JY{D_lJUi20TFiiUkr zGtr!>8+2}*HHX31_DuyQ+n9%Fj5dK@A2F3=j&O-x6C^@w4RO@X>#Iw|+P?8IrNV=VcTmjm_7wGx zDp!-kA`-z{OS$52Kki$p-KoiOp<@;0v1|hfp}C z$8boHwh)9yZN@k|vn-QIPb9LJD2%IPg(3`)$wW;)w)alsX(WpW=|PFzy`(iA8;26L zO41n=l^s@o@ZDiHW6lM3sW2#mH7=lx85aa=VC-J!{RD@*yuOYlh-LBfBopxP9e}Yg zv4fKT$*$)P#%4E2CH&^CSUQ`iV@v6-rd5XdC5cT>epwmba)gM<#qFGer|*{hDVERDj}fJ1oFSkuL{N zuZDd}7C1V125BSwn!6gy?|+{(O+t#_b58GG@>lr`lj*`jVsz7qDXk-Q*;rXfREfhh zd*;FCUBncY0bPrhVywQwi;qM5R{y;zegmy6QcDR`Q7WyTq51rRsKfRHC_u6{8B4_-PH{6`5hV@XMu6&jC?aqsgVGiq%dKyCeuQNv=a6z zxQ8UCYYy?Ja*kHMfbJkYrMu?+dJDK!aYhEsV3A3u$o;15JXbcK9-qSC1rkGV=O1(l zCtYF3D++W`zp=zb{&i8a8~(be1QZgKaq5p+5vEs6$6tHia`Za4bt?xDqqEg@Bfc(t@wy;VX&-3;2F-P zdr9*5Z2(BkQPS71$)iE0Jzsn!nyf5(XXej(TpmtmcR@YFEqqR4%N!nij2F-%1E5I< zz_cV{&->`4j-d0@V~{veMnXRzD#BJ@5<2#2}sJhFx9ZDySMSIzr+--8jY7Jx-5rD`AJy0GYg_yHh-6HC(WkdpIzpo zq4>FaD<$82DqJjIu9(&eix(00I#f&7^BU%gKD^7Etvlu_?*pw9@O!ZLpbUq)Hn?rp zq|dzYxlV5u^BnoD+M&h# zvhT5lg*{+^eo3#4?j_n+OUW(2l5CKUreimckB@){9SKbk^UC=L zsoO$Y)9R=x6k6%F8%OAhb6{<@X*=u+_F=BXh`d9_KPN@fr=Z$}jx8Bj!CTeHl>GyG z!ihn;XJ2U{sN@se&_-#8W%`B^3Im+8I&Dmhf5=he^)D}O|D{R8HIi|xZf@!+S4RaPiYEfb1_K`{eN)&USvY_dL99THdu&Dl7co6JZfddD=Gy%c94X9 zazx`(fn|+S3B+j}3r%6@A_E4`1xx(_z(-d{mC@hbGU+PY4m>cw6*QmiBchGqY6VRs zS7Wx!hZo*on484lDC{5b)WuRsx35?%ucd@ENt(q#merMxEpN&MCjVx6S-aJbKV~s2 zB&?cF4f6_+?vM0!itSvOcr$XY39PZtfnO?DmY*=$UN1Hjs;>)zZocHkrnr{N+duOY z<~K5A_zT30`BmfK1f4#*k+C9#A4>#hReaW&j`L27LDS4y^dq^yB(4X1;BypI|N}Ret8Q z(oF__vJeh|8O)b4uEuLP4|*8P!9i-6!G^nzwdTyozO{5>BdM@M|1)Jw%`>M-J_r_c3r#Pl+|Hv|B3r-tt5*w>yg-trpG2MmzZ^x9TKbdL1XyXP5 z$*2-nd9@4IRxzm}g@FlIBUfg9QSVaAtVdELCh1XFyzA@E!feu#fb(1i8~D~1yh zu$qn%W?Qxu>l2)^sfikfNiIPW9ZY>;byiTUSRA2^UQjs3V(vuRdWfo$I z35cpuieP1vi99&_KXu(zP}^bmCvY5!7cExY-QC^Y9fAcbUZl9YySsaFFTvf47K*!; z5`5G5-JSXG?Ce#po=I|(oacAW`F@riIUFF9^!G{aVbIxB6-5|mEX>QgBbbCszmUvR ziCZv__V{@)t64w3{He?gfsfK>6GE7+nt>up;OI!C)jsE8Tl-2CFNqO4=7}4w!XIrN z^oK+(Cd~jI9g3VOtuXDQDgwbk;a9T0LVEFB^c#*;)FJ&)&WLxy=@nbwN2(Gv-t(R5 z1aH-2`WS|)!KhH>8SBXTO0=3IXgT+3h5i^C1QN18dm12%+GJ;$lLsdsNc+lET$B3Y z2N2D6d@j2fmY$soEQK+5(xsAmTMr%Pu#mn{BOt8SK0$1p>BC7lOe(w~d=zxNMNLS2 zFr57k(O)%4LmT~3?ab1kV4fjz&v*2CExZQL&#ae$Mb~M;D@{LW$X}*n%9?q;T^ieR zFoNd0#hq7;Ix)1*u+A5~a?(R$3pxZFMx_k9k8j&= z7&-5E5tyP9VB$`7IwZ>MxgCMsI?A31nyF@k!R9_EhL`|nCIeS$#5e?)iO4E-@ zak@NIht=`&YG^&MIAJrlx8!kJ%A>l7Al#lZO!S{Q(wv*tzM{P4|4o(RaSi;VN;Q(s z|4Ws2@PVUn!Kq~G)Pc~LxPr(Y0b?^_W5n_Lnp5;`Nk+PSM25dVkOzu81<%?kr!5f& zRqcL*I?40Is7*hE^!vzg=B5X;f8q)C-=fuJ1uBR=!Yy~S(mW459uxR`&C`1ouiY~Rr8xZ(q zqp=22Xj@HZ0WOQOndka(umSxWf}z=}wN)EQpkwV)DSmu+8QMzfUxHSYllfxgzzd)t zf1YtO1UHSJH)$UQb5+{Yb57^;xkH%|SKJN#rbWLpTxRy$8*^wDgLb0rNHd5MVZ^S4 zkw^VRPB?JWw2^rVYdaFO|Zs75Z@N6GC%}jfd7A z$6PzdkC3^$QYjizh4tvw7=~w!EhD%p{eh~i@;my&>cEXDvzO#T?)MMA!MzN>UgwT? z>cbZCX`_`}V=#s^p*s%gyzD_h9D_mb*Vy}k1q}%3*`+1t?Wt51MjshxS?46a7>e!I zvk%!gRFur5E|?HBQxfx$j(Ti1#|>!gMp#T{*6b_COH5KzN$jrO9p3ZR8ls83xlbfL z5kdGN1_(mw4R6RVynIqg{70UCd?5Hoo_<0D^nE5osbM3}q?zEl)pHz3A1I0Dt}t31 z?kF`6H4ox_QV>!N-HJz|pJHb!kQsMiN*UsC^|R+AlvkWt1|RBlW%vpP zcyai*6VNU21jtk-<4kd(#hpz3VEF|(2C>Ry5X}(SEdED$kygG*1mXv`l7%bG8>jS|z zu?GG|cnoJoqO9=`=3GXbuTvM^jg+tB>y2W1ebkza2Q$7=S)2#ViKylLxlf6;b zXk*gNZ{B=oW5?m5xX?VOIC|r;UA#crA4&N@aOxK>I@Q1ZK;Bjxy$KahY6E0*Y!H|> z6M}dN_ZTZH_p_xd0YxR!M~_jSpzek({pmofTKoI0`jCAWvcl3; zBCmtPY#5X09;^a5(Bb~yGgJMv5Bj%lF}WOYa(_b_<9n%4CrX$6+Ix&mlK9E|E$Rdr zR#yZd2&G8K0w4Sm>UM(@JTgpTp)qyQvDp^(7^GWtX3DPJFAVOMWUO5MSj3qKj>X=h zhyTDih?w+9L)0cNA?~l5ANC_4WP(4$t{n7X+BBleD#i*INkq^0Siv9hg#-7`O|`s% zv+)UK7RG=AH>QSJMGB9+ppFj6HgotfFq1A$TY8Zqc{SzOek#THE&6P2CF zfxEL!#0HTia@>vR`4)E59OY{Ai}yQDwxEJ8nW`o$`X8q&QDGTz*jv2&CqAifZ&jgM zS$dOlam=KSK;ppb&YBiEUI$o}jgpODw60ZO#4Y+hNXl(UY36PBXrgj9Jzz1!n}ULg?ev7*8U&cbH9zu zTYtqJu52v6nbWrVD-uosp_GUEh}4PjjlV_dEx?Cd@2vt$Y_|}ZvaA_WSBN$c8wouH_o^JX0atsQkkjRxn+)ojeEP z0!;G}mF3Xf002J?It#1Xg8MwCl`0Xb8Qz=AoCkQPt#1q$1w&-6UmJ}Y+eP5(7d+1; z#TWTWTMm1$IU&V31O6h+x>CEEYjPR5Z`=_p`6w z4{C;OJ!{nW>Pg|4^;x;{mCZle?u@nXG&jEux8|t3MYm~SknAuinQ1t5!0l&#+ngLt zW?n!_qZ8(H;0R;--8-LDVmq8(O!3ek^;BGs%D8P4eP{uiq4-#E5t0ft^%#6c-#(2| zk0`5^f(-R+_3642l%Z0p#3%oGzmPXvIG0tbQMJtdsL5f8jZcHX@`v}ues7kjAiq>T zd*?4S;&dSanTwaL6??a)`BZM8WZgvsZQV0j@PnE{6*NQCS^7U&y?dXIe%hh zLY$Btetodv*io{61s{J;TdFlZe|$oA&yJ34wf=7@v;N%N{M<&zAn6_L>xHIGd3=Vh z1`0C`hu50=vqE+zFU|@wHHOG&F6`Khfm`*hY#K<@w`x{Rn`gZ~E5{*h-mKd-W_bpu*o-wT^@-V+H%xNM3&OYrh|l8 zB7BIK2nhc#~WoH%VMaRBYg2r^{7P<$cuwPnCsQ;K4(B`wf&Zp)$g5a&X|6 zTN{*wc&id7sYbyfS{gH^Q1)|dY@M4T?Sh@U8n=Ez=aY@14P;+%%rS{GidysGPRWup zWW&eK)NAqmOa}Q_+o>O_hEM1G?B_Jif%a_YsSJVPQ7dEz`+zgoD8k5*VA!h58sck; z!P+c^xRyjji$qp#D;_j%{q1JB(nzQb@KUhM0j>)U?w8f z2w3`%n%23DoW>xIF#(_ns}ei&vHNZR4^)GCMyMz=Q51`+pw7h?x1#xp_4^hiT9^B! zI?agA^N`LuA~_HGxlwyzm!1v|f2WFZni#k$Ua#om zB_`;@Rw@J}XNdMdV_b;rCuRrr45_oR@{*NYqXQ?;K~u_nZA ze%GzoxK7OL_+DLI3?I}aXcD*^h6kIeG3|I3h%5g)kN%KEfd^LMGw2#7o~TsI{tJ(` zJP{f%f`f26;k7ZnrtOJ&*~oZ5D4hFZ{YkXpJ?@$SmrN`_8{Vy<%E-i9e57Y0BR8fV z84`JSNTTL8{CKP0v<{%UKpprp7zGeIQN3EjyGZmi0a>jgeYSyC1b3WED_|x+1W6xs z&`#$KAAUSm!xRf4D*a_UuVZz?NJWN+oj4m=fxOh%P-?Vv?{7s$T)O|Q@jS4L1o{Ox z<^vGB?xWq`wLEJ%!gyiL2aPR{W@%`zPx(&~`u+@OKhJ7j4%KtPbJ?;3hhx0$66hyxJOU2Bw}?=U+2K@>~V4? zPSMBkyT1ew-a6x!Ft5a-JwBF&gx)?@BpO}bHwj}xG$*&=2;EUKfhcB`y9FyC+pTo?0!g<5FU-sFvUHZ3~%l3#DH2*A9+x00|w~GFV%RiI0tjvYR zZ~d>`Z&vSA_s_KF&@IEC54^Sv#|t_mN`A}>&Rbm?Ka`&(*}vh|6?t6ZJ{0@1t&scF@c@dF7TZ@af_dGayA%JAmD3b-)cd)zfW@+x7KRV?YRE6{%T`*AaVMiao*G$CSbvx>h(>7UX) z{W|<@{M+c;O8Nyw8@2x5*+mhb_4p06zra4XyWCfNx3Sz}C%1IjDA|!|&-=?tz=6!x z*`>L^3Bx?nMMi*kr_PJbn=(N}Z)>3EntPRrRhKk~3hTMed)v?U^R?GAd;iq?chL(c4pVN$^Nkl)N6w8%u<_}w z^P@E69g1iK&C*xfzh(4qnVwyh3%+t>mojrD0lRcT04XlTVBW|!IJE}O_iyF45qgHk z=z*sWOue4sj#$gnO$qtsLqLE+p-Vn2O6~kANimO7?Su-9EzKiLqC*JkM}*~TV~7%w z2PJY16CU~CO_BtEgMTUjr9x;ae=ZSAN!CB3pb@vsgk{kIs30j%Cdhd?9KOeX;C68G zYi^SL%kG2%)A5%qJUG6OkScbF%&uUV!JouX^h1S(CT>z_|IGUlNzN5!!U!E1p_3Oj9fWTOV@W58vdei zG;5YFUeOe?4)>P;a2K{Ij@icmDsxxYCaOJy;jzxsz~O7$ATuO?q@2PQCsOB^YHUGp zM1Vw;K7~9~b%S^E_JZI!t$hA~@tgAS8HnLjCuG`uPFJda7*Wj&=ya_zRe1%vTkK)+ znX}UvhR8;-z<tI^ALzWU8|@oWPn9v@k(HU&*|wB*v@QbjF@i}; za#a&oPNguoDT4qqdMQ~71xv$4TNP`ygnwl+rY&Q+)_79MZPM*5jjGjt{z?=O%|%En zHH}(1723s$hyTo-%77@Z82xmLCxLU^sohvA+8~lnjK}4j1}8#W0uS#gNd7*5=PFJS~E2St|azMFAa@3 zvHO!U>+YW)JCixb#b~;=#Pf>4+#CD*BjZs~X-4}^H5YZBGTy44TAwXN3(Yl-ZC*Z_ z{t>^%u}K9N*NXmk> zhTYZ$vm4&>n?|lGzM|ucb?@Zml7tkr@2>*+mFL1y)NHa#GYb=`l1KXGuT159X=c{3 zZ)AB$M-bJsQEL{Wddkm<8{-@|a320jB**^Kawl9r?WL^#c;nh+F8=yc<5=w9ea(qS z;W6XgjQC%90QQXfncr|;f1UDoqtCX2Bs#*;M(A)nB|t}kabFHoj}hFR+-xlDVgJ}j zTB>6zM%WYkd7IPV;|A)KgjHj6Uos3mkAN#9=p>O=^?YJY*b2AFf{@+36w^a0FUg_6 zZ@RFIaR3ES^J_m!N28mx!kVy@hhouIv79IcR{Q{6pq%Bd?@7ph%WafFx%?FzsA}6Z{$g131nj2bd5hgQ-{?D*ERn*M)8IL zSV~h3!)?G>y-4g<#t-t!Ng5xm>Riz1?BSSYYOgCFFp9AoEzheh5WFDti9}cNSM#@Y z4HMn_`E0!|2QN#E0DoHYt(=?k;m_muzP0iMbr0>XA84*0I<4q+fed0G)Un)Eks96- z`GRWl77Rq>{lybCA-Y|O1pZFKpE+#Nzk`J}zGzRQ=i$5VdaR(fXa(VLoCiVIrT(yX zn$L&f^U5ZlYCPTpLauJ#Z1>e*A^GG(qo(2&vE4PqbYeCz#uyCL*Wtt8JGo}cfHO%) zaz6Sx_I`xrbgH~bv9zyM4u;$ezcXXJ%+6sWTOeay#E4NQH9k-<*@LjYPLhaHqAuqj zIO*(==`JXT;kqeK*;Ds`l%Ff1SF3gep%IX4rmFUDq5u&yZehWPWKGj+>?R?|t+l^N zpqUWR&ofc51w$=aKWl|pGbVa0t5MB3N{{ZQ+*CioFZP+dn*-bRC#W&A21TPT304wC zJhd?i28(l{EE{1$ZbGo=&-pux?Y}H??|4V=6f3s$qtJ=>*EEfFQ8oz)4$~MY>6k(* z-ilY?b=;PPA7!OFha2(B0?@amGm%Oh_#X2RK{&&Bsbx(E zbu^dPpE$-PwZzyF;U?u%rtYAAWZMRh5^UB7&+D}0{sf*c2nXHnWIuI(eK$CO@ii^c zE`i^*fvKzrURpB4FN}_YfjUX2CY&zV@JAbAW-S=g#mjyoRWZo~KP~0oil)wT`Y9A@ z^?Fv2EbN}oA1-1%U5SuWkI1h}U?*n4!eWzP>WU- zQEc)18TSSz@BdSa-COD3a-W@}c5^*)J<>e}1!DZF;I=k8Op;CTx__{XBar?259;LY z{Lz~(WE5cdgO%tl6dDs%t?{h5ziIaF(>m!o>Bdjv!L2JNoUt3byC!}{>c=aZ2b%l& zWbnwbuODrks8ffzPrxJofoNVXly^7jOCtR##KkijHg20fml%+4KO6t& zzE5oAV$k9CY)UqD0SW8i8TetSL>T>3qqg@t<_&2WsZ2Z87Ty~VK$Ymf3izT!*uEkC z7Ck|T4?oDqZ==4&ci+r+=@-fL-WkeH_(eedmFiWHIQjUW(qti$4&Tq_ZDlUqgC^4j zfQ=Lv|NOrYr|=QxO3!9i=9voCxBsLZO-Ki8Ps1a4-3vdpDWnN$ENPB>hHO0qFYIq1i##ajtFt!=$YoKQ58|eNW)|HEt^6dEkXo{_2~SeD%#R?eoe+rN ze5C%stxSuboL3?++3-aou%vFHSF>G(L}tu~48#KcLerkFI$5Ox+s(jJMK)Xfbg+9n zVwsA=hdW7}0r!40@cY{Qj8^E-%!zKtyzF}dL$PepfQtn{AZViGquweGiiZN|hJGT< zQ(Ld(cSZUXQf3l@H(Vx@mUo2d&*Mk25|S3t7k7u@L_~2)NjX^)8B{ldT2ja;OX3Qp z_iQ!YPBcy@wl)ZUQ2V#Ugh8lvr7+VJBChbvyxA+Gme^!HrhDtkR@B!I;ylQM*qIqi zDwszkZox<*NdD4}RN_Zp$b#U*vQf0Vus)wr`69{khgy+2NYffNbAY7RddVW-BRS{4 z9cZJT1qXa=$>I}S{mNYFF(e?Nhb0MI<@p3PsD|KaSXpUK?F`CCHNy23?5(jk`cSOC zUoPmNt2I1afhx?P!N@5si+#@4Lm9*lBJ-^E`t0s4t^-4XB1L|JF@Swp4uQXwC zl}=VXI4qPyHW3(jC%yPHmwPiJBni4rxJwj`3$ze{rzk#S5NH~*Br;;*M-tzi#U4$- zxN58#vvg~gtPUue{gU`Tq%SF$)Pd1a43?KC8CW!4GOtv46-Qu1;zcw>k49oq7!k!0)P6 zZv~1~7IFy`V}9^B_|@c~n43xJtmJH>#8Cva+`I+yfoL8l2JZd3-}qLcZeMG=&NNJT zM|wn5KRp7UNB2bQm3!U^HMXu}z0<1-6d$l9#%c1z23!`Skhae576@@2j6Lkjg}EFB zcu7;9ZnO5Kth%jqLC;k9X-OJ^V7nLm5baW*W0lV1J$7Q;PtY=kg`S0!=zk_w^PwKZ zn7R;0vvBBB2wd14k%w0tMO_4lu%qRudVA6{;;1o-D8bR9Z){R-Gec&Y zB?PN;002=FwB&qJOWi^|yhR#?a5A|$o{QERX5^^)67Ce_Et_}?p~d8!z_B=RUeSbL zNx=c~g%r*51;t%8x#+oKpNvA9d2#SY{$2yB_X}a{5kktn9X3NaB|;-YqzjCedxWrE z4C;NU$cBO>YIrLAxY^L3lj@RnBZ4v4;1Kr#j2k-kDOM;5SDa!UdvlYOQ&@StF`ee$ z68lm}dL3qFZJyg{tmpl;nTwxiFNL6B>ZNB}N%bi|%2_4Wq=QxL_4;T$)|x5IT-VhS z^)gOyxBe?r5kQFCJx07|7Cqi!9?!U&QkU^*z_#f}JfS!5Wn}hl@rGQU%1->CIzA=3 zN-K7roCb>dkzD;g9Z3ODk{{1Sg|4WyKz$EYBMrn_Sl;~ZOmz+A=!6j$kag{t#_-MZ=cV>s!WsM3Czza7Xk8^qE+pi}R@&!U} z9_gtJ2N|<78}0+ v7l!~hFEbmT02^CnuENs)b->XXU}x?9|39!ccxwwe03|Q2B2_P87W}^ev|o0l literal 0 HcmV?d00001 diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/listitem.png b/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/listitem.png new file mode 100644 index 0000000000000000000000000000000000000000..e45715f914df0b9ce5650cd81f826565d794bc6f GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRO!3HEZ#7tid5-9M9ECz~A24Tjhjus6-LG}_) zUsv|KjDqY+yxD&zFaw41JY5_^BrYc>NGv&UGh(5%v^3ic2_Tqf;9+ScrKuZn^uU2H zQyfn*9&-yU`CQ%jRM<_jbEVs=+4%-On`#az=vrO%C^ha<()jUzeq*EHImaYp10cwd vh@M+!5EQwitFh7Z?ulO_J-(9;uViOPP?5c=x_{|>pv?@Pu6{1-oD!M<&SgTz literal 0 HcmV?d00001 diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/logo.png b/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2c1a24dc7dc7e8d989ff3c98eee2c233074e3c0e GIT binary patch literal 26933 zcmb4L5DQ2> z#H8W}i39izii@0{I|PD;_um&BB;z{~_$88uyplB1DjY6072L^-x=aX!0wOOZuIaP* z*T~x+zwbWK>RSK931vjMsw5WuIbs1XOb!o5jVhObD-I`(NFYUtZ7UiR?zAVBk$X** zOBXICcXFi8*4%J$|JHlMZ9i9TVfSKTZ1rgMXtYC+bF9sB70%~$y*msE>y6O=`^Dzf zOW)UMuRWPbKHvLws9UzAc;Pu7Eopslx>>E97kqdiHA$~D>10L5#I({)t(bdefU$FP zOBX3;j@MeN&`^fMcRk);ZyX(sG-`vlPyA4y;Klp;U&UVtWTMF2PgLNwweyD6ld_tV zyihQjaHsDzBV<_wJAy}&wDa;@4SEFs{McSwk>L0$u2jl`$LXPdG}{(elm@b2y&}mCxdpKKhdA!nU zO0*+wQ_RlAr70*VSoNLDcJgm_%+$JAZ~Wrmy@1%2xO9CC^@tR znx7{9cjfktVTCq=Ej2n9H9D^aQc`Pa>!E~1N6U9zuLV65taruIqDNRn7S%7*M2oWIWH%tD`TO+} zDsi4V#oMM_j0|uy$q`cv_8&i~e&*?;d?#AdA2am+SY)tm@t@(a)opJa>6&Jue!Ig$ zjX^z0^44}jc{%gW-bB8s9w8{0?81Tqhk=oi3NcMRJw20$e@o8&*GEg<7V|&M{F!#T z^GVu{cg}R;3KHXmBB#1!YwbYvtTT>5xo$VHOMB%zbXC_1HTIGBB< z-;HyzQhQ|zGwaY4(02@yUgFUz(%%cc{}tQuTEL^J*L9o4kC>R4$9nYpZ44d#8==zv zosn;8Tie@L8YP;lj45(Z=$%@HHm~1n% zW%75Tk!yAHJlH))&m`HDe-Wc{cS+NGwwmEEQmp2;rn;Xg>O~kn(`s4mOkpQmjfK9D zq$f&#sfEwL@!gr`M2RDbuVMR}hBTR=SFB;H*HOUx_nT6W?sJt!_hb-O!=^5@7^HYc zQzxfY$qMbX03F7Z--Ck(k1fg1DHJ8e7{hPT6wT9jc$!kUWz5SPe)>GNU`*iYVpHhu?#`nC41V3kgTJ4`vD~>+Y zRFPl9gh5YUvCmfW#fMnmgze+KX&jTfZ>4p-4fm6B76@WSJ7J;PpC-Q$GF-^oevEM; zQ7TPt)9n$j9DWxgx8f&RGV0vdSQ10T<1lY>hv&-x<8xULCT4s6MrhUWp@=%Ajt8CP z+CTh0`;DCre!6GO4pSF4wst=EyB0s2x{?|t*`&#@@X;CS2~s&+^_-WK;RU~p6#_TL z*4JE*2jVkgN$e@#1qp=cD2R~!G3PEQxRSM13S^$J(F>OlqeqQ-FFi0hl%^sbxWan# z!MnrD&Shtqcz$6)*u~pBs?s?IyXWh-Z=F9CKK|E0vjjOBRw6Ev|9!l_{WI5xRr^!5 zJP!fCoEBR`L9=|8ybq39I^85@VxpjKF*!FyTs!RFzql}+ODH_#+WWiljXU*D-$wh( zl?LAWvp0<92oaVEfdw8@xLU-%IQ73CidZvm(71Jr6}XvtLh_|$9HN-5h>UBC+tKF2zlj`b59}-yc$&U)9i_~^_q}L z`EMRGWWhx-=`c%;)^R1Uo4>jfrn>%GUrKt2NgZkTM z199CLpx_|wWS?LUVjy+mxd_Vj( z!zhQ8*NGXeN;KfEPRqli?s2xlV1(CUetqZ9AC7SK(t_mDO5=7C3rEKaMtb^>_m@*D zXv@pX1rTg9vRJiznVII{D9qPA0Gw6(URVvCp1Oohk!h?( zH8$WD2a475Yd{10#Gp~Q{yX6<5uXbM#PsT5#tXciQYxDX>-}za(2fRFfgWb4sW~kI zQ%|?Gv&)z(*Q*_7HEJnH9C{qaf%x+71G1G4tf3ks;U1#h#|QStEbnwp!d85kJicR?4g7}3+$Y3|S@jKAN4EPG)}Px2Od$zzG$ zeRYF*hNnKJF z)I`Swc@=etW@4)fV$OR#W{T96rdlA&4skM*CK*x65|?Ck8AQZ3VEK9k(W1Nhk55LOzQ^E(^`Z?7ZZ zKEuk&>ScdlpB@MLdnJaHVok<9S=JaSs$$JjhiY9z2YY)zv)^ARO#}o5cc;@_RKD}Q zJJ}jY;-rW5PET{aWnd^d3Wj^3Nkc5+Jwt7^lNHpKMXfC4+%jEFy&84c|d z=TwnOHZ9?&i$eiDLzp^0vvJ#vc3_~$ds9=2y2i#64$p&Wm!k|DGc&VHaH|5cv`L=W zs1g6bM@UJHz^1Y$qMhsNT3+_Zs@gHt`&+uQpZl9rXVN-ZF; zsJg_X#YoWNb(B${UB>Cb7tDd~?zK0bTYG)Hq7aEiZoCFMce%f$*Q+_Q}+^8Y?y*k50v-MH6+k;`qq z7r|a;vbm}s!L}E~lVGf0velSGKtx>F-r6c3`Td)yRFm;A`D5B9A2I?wpMb#A*70$N z)p(BhzUKg;7=!2C&Nt`8I&nI({#@x#gh6+=w*ehC6I7&}oV7o~!^8EfUdS*Y_Pe@x zcxZyAa`{Fy@L|Cu=#hXb0r~0ai7)WM=ft4V>1b?pl&5mYeR6U&1B}r=di)sUwZMBv z!+;A;D@)6Fg5Jk})l^koBp6dtXVMl$$cJiN+}#bvo85P3SPUA5D~2j0n2veB}Xu4gX5~}UzDtXe=)1QC+`h|)B zFP?c&9UYCr%)(Lx-Y0O$@1$KvcWNEeM_#0)>DiH$rdULLg<8NdavWlnK>v$ge@5|zx!oU1o?&q)4jCwSiV%u<Jcm^@04Xs>~yubJvh4l?As_;c{tU9Cb<=({eKF>{JB5rs@glAP;&eP3iJf^Fw z>ltXEk~4OmnVfx`=r7_nzkL1Lv_6_Ccnt>E;?UF-9Wa z#r?mdW4Go9H7x|#TJ(P0KfP3GefHcIf5hWh5dZ;bK|%4PqIYa(Vq}ysH~*9I-$sWe>(5B3vVAYu!Xbu0=FmF+G+jR}=fw^` zB&)e^@9+taP^;Y;rRB_X^n8G-GQ-&GcrlN>Y;-#X-ACo%y4n)9nHHKwhK2A}#_W}y z-zJ>BPIbYyQ3_N|OHfTGR+UuLf5vA(s~j&^LFC^$Zz3OE{+D&xNw|x?#uGH1D;XuT z$7>O3w!XVdHzRCiVd0^7-71kA4Cs^$fF>lkxaueOoQ}#n*GSh zvyZ^cDLEw%3JO9%K=6PnDYYBx>e5f1eCI06G*6JDPLZQdhvcE7qt`@8n8k@vsA|ue zZSU?b0TP$R=Y4Fb0)k5$=EJ3cfx4+*6AdsC!H(P;9p=hZ@25jU!uod#@VOSXG z=x*Q=I72lAiW;C}?(gqUX;&KFZUVVMc4vFr@ypQmcuImQJ;G1+1*!!46f>eDPx9!# zKj^8J?pK0p63Ekb^=1GXlaq%qF)@E>t&9y0LVvNN z)59zcv|dCE@&L3!Oi67hI!;4D0lB|Exfbv}-@-zT2rVgR{nTd;`E9AEjY?qvCWHZD z06rmMgGr5ryuQ{plQnK&!s|~>%`9M6mXM#c_S0;0Q=>B&S%txCCZVUkfRlt9gyg`8 zN5$cKAY?kw{N#L!a5$|})5XQ7lLo<;7%f~rYy#x|^_-?yHau7mK4{6PXomZm7 z!+T%w^RJZlGj5PsI3I1N7~d^McWWXxQ=L6K$p#6)iQUVhTtuf0ncvYSX~@YTr?Z>E zCnY6u%7{KJ&(87yBr5a((8%f8SvL^r5>isGyg|J?KqMSD<>lpXgVpV%kQqv^TgliV zAt50qc2#98l3_0~0wJp1CGECTw29f-&WYc?`Ke9m;jTOrlaluH3ktGnGp5YxH#!-e z9=D#PVoOZoqe_RNy<%m@!NJi6O*DV=&mY=B3l2OZJZo`rIOS}Sc4q)-S-^VWAz_ec z?h16({FN%v9K@CAVn+wnRiz5u{qW&KAv!6Kq71V9%o7hCUH{|F*=A&PbTkHW$hzpB~1dC@5 zz)QpcPr-^mf6NWrKX_hb3HyzHCVH3m>r?{DQ0sqt-l?Ik{`V3WSCSrokc8W=j-QUs z+CGU^iNo*epiiDUQ3_fjZDCQckj`n1K0GplB=X_X#z9R@4b8~62nJhVHfZ?E46D-! z7>);by6J(kG%|7o?s4KnweExI&FRK%_!ka$b1$!kDFCT#O&uK{1MTb%R2CK%wzFv7 zzLoR`pd<*6tBkqJ;_rO*Gs4T4$^^&=ouoj-fETl}q6PIng!~OmzWsgqa0xShcs0fp zwaUs$@)yOX2N$3L_e7vsyOGh&@{%qtE{b4BOLc;ug+l%}?6Wg7DQH+&I-m_#tNHlw z)i*X?tH{aiv84?WAJt+@e96pY(e3c}wej(}=^|v&r#C58DRmhOAc{YY6cSotyxzUI zw%GkcMnRa2xr+=}v|=AoxS5nk;I9smC2~PGon1MyNJ<`I-VaiVE5}ZhQ-|pPV+TOD2}qlfXna z=*blHCfSQ;m5n8O2a}A#B#4{`3&w-9~89(1-%k} z!_(9FVDiU-{alj5KlkFri=;oBo0%R%BkbtkGc&^qRkDwflCikPBb>IDPdc9inclw5 z|Lhc%=UaF&Rj72Rt--ZC@{M;15edm8KUrIV-qXY5VPS18D1@gepH{D2x7ys<&CRX; ztyF>>0x9XYz*?)3yQ0EFL<9tE&~96NFLt)E$VD#aRA?QXoyi6KZ%*OB+8i8I;t>(e za|;VUewWClm(58{O+9|ErnJNA_m%dtM*?2^!OI>s*}mCC&`u#NtVL&0MI$y&Ep&H#eVKUtd?g z!kDundO4E8ZE$dM(g}gsNvguZ!CB0f>-_``>ssep5G*~;e@jnCL6P&z4QS{ZkkgBc z`@yB9d%6G(bzn_gBcc(0DaA#xKS{{Wer_~mWutrh>Q$NsShp)sLD0#xGS<3`7nD-m zmV?P6JUl#Tp4)&TQKk)D+ah6mlC7&MC@2sS5&3u>FW*Wip(J>YG=aZ8vVZ?Rsc^13 z>F?jaD4^>QECyKOxRdo)-}PH?q>Ec#SH|Q3YeqzbiK%RvVqkGm;15{!%y#Fs4#sRt z0Oz@=sS(1zTXRu-;=V+I8yOJ?8GyehmuFT(7q+~f=7RoepP?owc%+p_d z3~R<4w4Eds9;ql2ByMC53m=s-mXS2o57G>C7RdaE{+E+$qv(^(gWuTPY+H&3eo0{G zKq-!s_R1KCl=x66{l}K!YfTx$ag@^W^oKH~vR>Sm5z@SiD=~XFO43fxf5PMLN^#vQnGSAbL&raGD;!xaXa^BeB*FUq$OIGzux85Z?-YYM!fd3iy?Rco$I3%OcQ zKM77%^(JbNCU;A*$>Oee_5X8eviUi{f8ZGrFGdtVF?AGUKZ*6AA z^9<+*Dq63qElo{NNq@4F))l@T@lW1{JQZcusv966A>BttM2NGQQn?>Ym(VdC+VDCq zT8z0G^5=Jyl$5vuaSLx}EZf9d+^&vg8>WyZ!UslgtQRKUPxjxxe`6ydA~xUN-Tj(z z^}qtv9|jP7xw}oEiwk>;_er3AUkrf?E*_q+haj7zq$JR?l%^A9jdErv6qS^&U%h(e zJxTL%et!NP1XJ^jIT6fe--ag&^YyL}_sq;pf~%4?T3Xt308<}a?=JTt6*AJu-P=QH zod`dQSm!u6IsNw5*Ik-LlBxkQaRpT96VPkUK(ne8co93h7I6Lg+Jwch_)JoyWGD#8 zBw_XTbAK+zL_0CMNFarZ>7f~mo9+_@sA-vOuf;K!?b0VW*s~Ny?KKbfcC*y+W>#`8 z()~zQkdh-ZYvCoRj|qh{gHE^wFX9hN;2JcCuZBm1^4(!P`C z$RYYEv;Tg*K14#5{=fv*>vzH%e}Xp&aHnv=XWWkA*lRsKJx}22D&eC>cn1as>Pe2% z(JLqnWfv)?*O&q*GBX?Hb+njiNmMA;sMgop>%mG-Z=?SzRKR@)9rVi&Vq-x|l}4?7 zTAp=radD5^Zq2Ik1%Wi-$wHsR02L!UTwhmJ{${Q>t5~Ax<#TgtW~8LLH&?aRcb6== zG||%1qWzT`C}LE3`T2NR+x+cqZBH|7Ou^kLk39VR#6W5FNEootZn^3k7}!?>4s*jC z@9Qb>;NQ8dcM*WLxqV<_WmU)on=XhWIgB=L|4?#}#L^2WELg#2DmJ#0;^VW22Y)Fk zsmmZe1WRjcS*B(nF#Pgg__}wQOcO-1kGoJx3t3EzKq5M>r=^t>q>URPM zp~fAsUD*Uo+ywxR9nYE^UA;`d+3VwtjqbfDduwa!&bo+cus3Q=sBu&L=m1_}0XTnU zwZ9)pT%4`4)0Z}J(8PrdqS|)t#J0bC{{-Xky{HNQ09y%_v7ZdruoG1I4i zQ*FN!6Qllw_p&(?;u|~Ky+8Ui-*i@0A6vIE@#f8&*2jm3VL*8sru$-nZdMMv3qeya zxeNmcKwz5d4h;n*q^gQ-1?XgdLPJB(dE7$QyLi|9-%edC*~lI-rj#1+x6%zU%EXbS zUkMRfGcz!tq{&g=EhVGW%2~ernukEx;@?W~FC=SNYp-)=k&IK<5V;J^?{{T?85i z1_oYvdHEmD_!3RV+A^K0)%oi8vKMEYCWa;#iqw{O8lw1>&0OU!+kL7TCc{EB#W717 zQ*U$x)Kc68Lh$gVV1*Ly?_wi)NGGMm>H^Ax*5px-vo&A^NME5pr$nm|ox&90n zj`rbSB`7qbNK~{84BA!@k5GlufZ@0Opaay0TY%f+v!Ya4SXj21ht%6~JOe(irwb~- zfB$|jt`d%djg2iGJMY7rxylhK6^NX?eD%zQ>;Ry&9NAHAc(}Njd&UM8+HXPkSFVf# zHm|7rV#D6v9_RBFDg?A|(S!TP0(AxqEG#UOYV*DlVZVRqv(*wpjrSrN>r&m5Q;%qA zStyZ-Z+!%Us&-yVc#4cquAvzYN1y3ruJMxW2Vg=RQm^}#f+LkpUO-6ZRSdjO)Sll) zM5N&sw_sC@+bGgcrRLBXJ&qwj%*2vQHO-8>&qxOt)_6VL3@=YbKX7qFI(O4e8(7CP zd=(WH8@9H#&?n-0`QzUD`ud_lrul-bAMdU@fcnoW%LhdD=YM+>o0?kB&E6-gF7^5t z6}6e0d|VFmr_I7Ty1Kfw!J3e`mQ3kPnL_k1FanRp^a%kkSz&in(#!gUCZ7FJ8rIzG z%eyjA3LgRiW=a67aEm76$ao>FG`@}7_VclbJwFErN5QkF$yMJg69>I!x9v2bggJWB zZsVpvBY-sW1^_VOR2Bnm;AcIK00KVuuuDzzy79fsS>-pRT+IWI1pU0pBZ>N5n+V}t z1kDlgJzK=EYDZb(&zB-Pb@w8%G9NY_e~x_gvf1}!e#hh5AglfFA1R|{3#@@<51M!Y z)wG_$eY~*K!cxlP=mB`T4A*Vge`Fs^^?(*y^$GX16<SNJ$+&S zV5W@qzt)(7`2-YCPVeJo;=DE22Ac_UHP7oQ8g3R!YC1Y+r1)2nZEfe!Ttn7IWMt%z zMl}`#oF)b^b#dAxE%uG}im&|cR;{4XegU5oi)jj~uA%W6eCeTqsN7f{Fv;3Rk-;{8_lo-u^IDQ?1k4PT#8 z@%@WObhKT$$X!35SOxrh=j2~}U+Y+&E>N!vE1LAleVUOd-!dUbzEr{^;a)y+a+v2R ziuL(urS$t;N^@el=s6VS%UAYpws&TODiH8$yCSKqs_G;jNO={KJRf6Y>qI>dG$TB) zu20rvfipG^JSxZL=4~CD9}Nv6{O^CE_XWe%kNHS2M5Lv?8l!fG*f5;;nx9oPp54|j zsDZA{?)7(`8-SQqfD4vJhKKPNyTxfJ0679R{0OvwDrS?82M0O1-%(?k1<4yQ^bA3o zc@u(fo*xN^uDGZ@2^JIeqlyQ!-;?TFD16}Ysu8)D&Kv18IcE`jVPJ1!VTIWJyV%IE z)~azaJ^dg3TgoG}x1P&lDZhtx?~S16%Q-Ju?bjH6SDRd4gnxM`RQmR2f^%vfh~Wbo zYu$%OM;OqO5is0EX0IAu$fB@BZcHr$UTT1w^Y05BSm!%#b|xew?46vf*##`TX4Pup z?(U9CK!D^k2{-EV-CFDT0c$sR4*bu#BOhEBr475?fygv!64SuHHjRt-4C?4j_(THOI87cg~1an5_qFf~X2t)grffA>;kQhO8p z0jDs^P(H}ks&G^i)Y5JYRWf-nl10lf37bOrXznaNPk_dkyQ5~^Ov;_h_RZO^p-C{- zU$GieG=kePrpCnpGA*+z3Cz;YuBCf!uCe+lrU)>0^5WLvF#QS{p!Jda`S?)J)~T0S zHNyw!Uew?9iHrLD?CPR$pU9IA1g75Lt|wNAm?{-M>X^OYY>U;D&s0v*;TJSa%+z=w z#0dvq0o-$y0EImPVeJj`(B0PVu8!{5r%gT{;PH8H^h8Jlr-|E+ekL)Q`No7O?jU#> zWhuK0lv1b z3oLUMNsGXaWOoR)D)7}+&S&>ctHyveLOm}KfPrtiUh!TN)~3f-s{2gK%{_Ct+U|#8 z(BMFv|9Av6K`CH}f6H4cM#sR&Ri*cbOgAMrm6b6$t+Z&xtqTbW`NKW@o;!H;0*o}9 zSG?2z>?0x~u9XxO|CsbXu6l(|MjiLw0aCXHIXwdx?gMIND*Dd{GE&k*(D92qO&L&8 zQ41^d>j&L{`t`ol03N3Ap1o0w`Q;9gB`rIa2rH%1xuixc`k=!-7>a0i|8juPK*TY( z?M?oUiR01Po*M6D(^<;D!a^gJeKr%F?m8VrSK$?UXpD1we2mQ-IR@?z-?rv!EQgd@ zyxik9U4TF0_D=+e{NJ*(*Pzb$0WZbG9gin~A!pNGCoLx@hkaUq(-wo`Qh*U zyFrDW&Y!0nKexd~EZOXje|7*X)7#f)30w!pXw=+922{i9VXI2{#09sd21m=!)FL8J zuVCsW+1}32z|J<#w-o?;EBs3t5aYIw6TW@3S65YCAD!EJ^&&#zEdH3@hyq(z9eQh% zqJ#XORc&T%y=(dYy+--<@jNK)_$p5M^vavBTmD2h-xvh~(5LN^P=qePsxwl><;`A9k-rC76HDdr0b3aVRZQKF^bgMyv|>QTOqFYZ^Am!Esam(AF1 zG&n9XA0~dRWwhZE5ByT}0@!YTEo<9u{J6Nd%RU2b0u{vH=gaH#IP23jOWrrKO}0 z5)%{Sfb9xfMSf(;@zBG0Q<~3vwEr37! zddD1}i{4hcV|Wg8NBx*qZf-Y*kw9VBC`bSUdm5deO5Gdtk6JS`r# z*$P^#p{6Pf7|~B^u^WlW#rCwVTfY0-77yui*tY557MAtlZVfAFISnV8xEXG1dO(pfx-_)su1amp>v@D;PghzFWc500O4Ow>2-4I@e zuK#U7+-DHY30eBr*_&91Wi@0iSFd&Tpc1*n<<_y5{KXkm0egG?P*ICbvDb;~rk z(L6K#@zX#t47D1`SeY{t3B?Wtl%NDeuQr0 zccx6|L>UTQEK~R(G&mH4ow!hEI|aMTbOp-v1>j{Xg06phgBN!`UtC`Hf_wA>lJb+f zjLa{uW<$(+{m(ZyH*6A;lJ`P~d2wu{fd4I)byn)j$jCIl7WCqRgKC6mAwf&(kAvLZ z-9^D9Z1>#yoj|;}nZ{;P`Hw_061{sMiSAw~@Zn|`T288QD5V~1HA?mlXHGq-)Lf&? zNcw2G1E;}d!(bdu!fx5;tHC`Lr{x5;@7ZJOSfKRI=n}Ok(9-?PtD7dbjZr9jK~gq7 zkqlP?ACQ7$YYDSv8!!44=me07cB}O356mPaLgzrdp@IRn{r5G>%%kxvfe*qW=U_PsQn~EWeo0;W4mS_~kIV?Aw{d;=6Uo&X& zD3Jyk%jm3s7FV0`qWZv4+swou
    iqU(V_fBwX^d}2|D=Bk$roABOZOF$hQ9i8_E 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 literal 0 HcmV?d00001 diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/pygments14.css_t b/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/pygments14.css_t new file mode 100644 index 000000000..838782b51 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/static/pygments14.css_t @@ -0,0 +1,401 @@ +/* + * pygments14.css + * ~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- pygments14 theme. Heavily copied from sphinx13. + * + * :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: {{ theme_font }}, 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + font-size: 14px; + text-align: center; + background-image: url(bodybg.png); + background-color: {{ theme_background }}; + color: black; + padding: 0; + /* + border-right: 1px solid {{ theme_border }}; + border-left: 1px solid {{ theme_border }}; + */ + + margin: 0 auto; + min-width: 780px; + max-width: 1080px; +} + +.outerwrapper { + background-image: url(docbg.png); + background-attachment: fixed; +} + +.pageheader { + text-align: left; + padding: 10px 15px; +} + +.pageheader ul { + float: right; + color: white; + list-style-type: none; + padding-left: 0; + margin-top: 40px; + margin-right: 10px; +} + +.pageheader li { + float: left; + margin: 0 0 0 10px; +} + +.pageheader li a { + border-radius: 3px; + padding: 8px 12px; + color: {{ theme_darkgray }}; + text-shadow: 0 0 5px rgba(0, 0, 0, 0.2); +} + +.pageheader li a:hover { + background-color: {{ theme_yellow }}; + color: black; + text-shadow: none; +} + +div.document { + text-align: left; + /*border-left: 1em solid {{ theme_lightyellow }};*/ +} + +div.bodywrapper { + margin: 0 12px 0 240px; + background-color: white; +/* border-right: 1px solid {{ theme_border }}; */ +} + +div.body { + margin: 0; + padding: 0.5em 20px 20px 20px; +} + +div.related { + font-size: 1em; + color: {{ theme_darkgray }}; +} + +div.related ul { + background-image: url(relbg.png); + background-repeat: repeat-y; + background-color: {{ theme_yellow }}; + height: 1.9em; + /* + border-top: 1px solid {{ theme_border }}; + border-bottom: 1px solid {{ theme_border }}; + */ +} + +div.related ul li { + margin: 0 5px 0 0; + padding: 0; + float: left; +} + +div.related ul li.right { + float: right; + margin-right: 5px; +} + +div.related ul li a { + margin: 0; + padding: 0 5px 0 5px; + line-height: 1.75em; + color: {{ theme_darkgray }}; + /*text-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5);*/ +} + +div.related ul li a:hover { + text-decoration: underline; + text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.5); +} + +div.sphinxsidebarwrapper { + position: relative; + top: 0px; + padding: 0; +} + +div.sphinxsidebar { + margin: 0; + padding: 0 0px 15px 15px; + width: 210px; + float: left; + font-size: 1em; + text-align: left; +} + +div.sphinxsidebar .logo { + font-size: 1.8em; + color: #666; + font-weight: 300; + text-align: center; +} + +div.sphinxsidebar .logo img { + vertical-align: middle; +} + +div.sphinxsidebar input { + border: 1px solid #aaa; + font-family: {{ theme_font }}, 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + font-size: 1em; +} + +div.sphinxsidebar h3 { + font-size: 1.5em; + /* border-top: 1px solid {{ theme_border }}; */ + margin-top: 1em; + margin-bottom: 0.5em; + padding-top: 0.5em; +} + +div.sphinxsidebar h4 { + font-size: 1.2em; + margin-bottom: 0; +} + +div.sphinxsidebar h3, div.sphinxsidebar h4 { + margin-right: -15px; + margin-left: -15px; + padding-right: 14px; + padding-left: 14px; + color: #333; + font-weight: 300; + /*text-shadow: 0px 0px 0.5px rgba(0, 0, 0, 0.4);*/ +} + +div.sphinxsidebarwrapper > h3:first-child { + margin-top: 0.5em; + border: none; +} + +div.sphinxsidebar h3 a { + color: #333; +} + +div.sphinxsidebar ul { + color: #444; + margin-top: 7px; + padding: 0; + line-height: 130%; +} + +div.sphinxsidebar ul ul { + margin-left: 20px; + list-style-image: url(listitem.png); +} + +div.footer { + color: {{ theme_darkgray }}; + text-shadow: 0 0 .2px rgba(255, 255, 255, 0.8); + padding: 2em; + text-align: center; + clear: both; + font-size: 0.8em; +} + +/* -- body styles ----------------------------------------------------------- */ + +p { + margin: 0.8em 0 0.5em 0; +} + +a { + color: {{ theme_darkgreen }}; + text-decoration: none; +} + +a:hover { + color: {{ theme_darkyellow }}; +} + +div.body a { + text-decoration: underline; +} + +h1 { + margin: 10px 0 0 0; + font-size: 2.4em; + color: {{ theme_darkgray }}; + font-weight: 300; +} + +h2 { + margin: 1.em 0 0.2em 0; + font-size: 1.5em; + font-weight: 300; + padding: 0; + color: {{ theme_darkgreen }}; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.3em; + font-weight: 300; +} + +div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { + text-decoration: none; +} + +div.body h1 a tt, div.body h2 a tt, div.body h3 a tt, div.body h4 a tt, div.body h5 a tt, div.body h6 a tt { + color: {{ theme_darkgreen }} !important; + font-size: inherit !important; +} + +a.headerlink { + color: {{ theme_green }} !important; + font-size: 12px; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none !important; + float: right; +} + +a.headerlink:hover { + background-color: #ccc; + color: white!important; +} + +cite, code, tt { + font-family: 'Consolas', 'DejaVu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 14px; + letter-spacing: -0.02em; +} + +tt { + background-color: #f2f2f2; + border: 1px solid #ddd; + border-radius: 2px; + color: #333; + padding: 1px; +} + +tt.descname, tt.descclassname, tt.xref { + border: 0; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + +a tt { + border: 0; + color: {{ theme_darkgreen }}; +} + +a tt:hover { + color: {{ theme_darkyellow }}; +} + +pre { + font-family: 'Consolas', 'DejaVu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 13px; + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border: 1px solid #ccc; + border-radius: 2px; + background-color: #f8f8f8; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + padding: 0.5em 0; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 0px 7px; + border: 1px solid #ccc; + margin-left: 1em; +} + +div.topic { + background-color: #f8f8f8; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + +div.admonition, div.warning { + font-size: 0.9em; + margin: 1em 0 1em 0; + border: 1px solid #86989B; + border-radius: 2px; + background-color: #f7f7f7; + padding: 0; +} + +div.admonition p, div.warning p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} + +div.admonition pre, div.warning pre { + margin: 0.4em 1em 0.4em 1em; +} + +div.admonition p.admonition-title, +div.warning p.admonition-title { + margin-top: 1em; + padding-top: 0.5em; + font-weight: bold; +} + +div.warning { + border: 1px solid #940000; +/* background-color: #FFCCCF;*/ +} + +div.warning p.admonition-title { +} + +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +.viewcode-back { + font-family: {{ theme_font }}, 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/theme.conf b/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/theme.conf new file mode 100644 index 000000000..fffe66d62 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/_themes/pygments14/theme.conf @@ -0,0 +1,15 @@ +[theme] +inherit = basic +stylesheet = pygments14.css +pygments_style = friendly + +[options] +green = #66b55e +darkgreen = #36852e +darkgray = #666666 +border = #66b55e +yellow = #f4cd00 +darkyellow = #d4ad00 +lightyellow = #fffbe3 +background = #f9f9f9 +font = PT Sans diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/conf.py b/node_modules/pygmentize-bundled/vendor/pygments/doc/conf.py new file mode 100644 index 000000000..864ec7a15 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/conf.py @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- +# +# Pygments documentation build configuration file, created by +# sphinx-quickstart on Sat Jan 18 17:07:37 2014. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('..')) + +import pygments + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'pygments.sphinxext'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Pygments' +copyright = u'2014, Georg Brandl' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = pygments.__version__ +# The full version, including alpha/beta/rc tags. +release = version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +#pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'pygments14' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ['_themes'] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'favicon.ico' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +html_sidebars = {'index': 'indexsidebar.html', + 'docs/*': 'docssidebar.html'} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Pygmentsdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'Pygments.tex', u'Pygments Documentation', + u'Georg Brandl', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'pygments', u'Pygments Documentation', + [u'Georg Brandl'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'Pygments', u'Pygments Documentation', + u'Georg Brandl', 'Pygments', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# Example configuration for intersphinx: refer to the Python standard library. +#intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/api.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/api.rst new file mode 100644 index 000000000..123a46431 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/api.rst @@ -0,0 +1,316 @@ +.. -*- mode: rst -*- + +===================== +The full Pygments API +===================== + +This page describes the Pygments API. + +High-level API +============== + +.. module:: pygments + +Functions from the :mod:`pygments` module: + +.. function:: lex(code, lexer) + + Lex `code` with the `lexer` (must be a `Lexer` instance) + and return an iterable of tokens. Currently, this only calls + `lexer.get_tokens()`. + +.. function:: format(tokens, formatter, outfile=None) + + Format a token stream (iterable of tokens) `tokens` with the + `formatter` (must be a `Formatter` instance). The result is + written to `outfile`, or if that is ``None``, returned as a + string. + +.. function:: highlight(code, lexer, formatter, outfile=None) + + This is the most high-level highlighting function. + It combines `lex` and `format` in one function. + + +.. module:: pygments.lexers + +Functions from :mod:`pygments.lexers`: + +.. function:: get_lexer_by_name(alias, **options) + + Return an instance of a `Lexer` subclass that has `alias` in its + aliases list. The lexer is given the `options` at its + instantiation. + + Will raise :exc:`pygments.util.ClassNotFound` if no lexer with that alias is + found. + +.. function:: get_lexer_for_filename(fn, **options) + + Return a `Lexer` subclass instance that has a filename pattern + matching `fn`. The lexer is given the `options` at its + instantiation. + + Will raise :exc:`pygments.util.ClassNotFound` if no lexer for that filename + is found. + +.. function:: get_lexer_for_mimetype(mime, **options) + + Return a `Lexer` subclass instance that has `mime` in its mimetype + list. The lexer is given the `options` at its instantiation. + + Will raise :exc:`pygments.util.ClassNotFound` if not lexer for that mimetype + is found. + +.. function:: guess_lexer(text, **options) + + Return a `Lexer` subclass instance that's guessed from the text in + `text`. For that, the :meth:`.analyse_text()` method of every known lexer + class is called with the text as argument, and the lexer which returned the + highest value will be instantiated and returned. + + :exc:`pygments.util.ClassNotFound` is raised if no lexer thinks it can + handle the content. + +.. function:: guess_lexer_for_filename(filename, text, **options) + + As :func:`guess_lexer()`, but only lexers which have a pattern in `filenames` + or `alias_filenames` that matches `filename` are taken into consideration. + + :exc:`pygments.util.ClassNotFound` is raised if no lexer thinks it can + handle the content. + +.. function:: get_all_lexers() + + Return an iterable over all registered lexers, yielding tuples in the + format:: + + (longname, tuple of aliases, tuple of filename patterns, tuple of mimetypes) + + .. versionadded:: 0.6 + + +.. module:: pygments.formatters + +Functions from :mod:`pygments.formatters`: + +.. function:: get_formatter_by_name(alias, **options) + + Return an instance of a :class:`.Formatter` subclass that has `alias` in its + aliases list. The formatter is given the `options` at its instantiation. + + Will raise :exc:`pygments.util.ClassNotFound` if no formatter with that + alias is found. + +.. function:: get_formatter_for_filename(fn, **options) + + Return a :class:`.Formatter` subclass instance that has a filename pattern + matching `fn`. The formatter is given the `options` at its instantiation. + + Will raise :exc:`pygments.util.ClassNotFound` if no formatter for that filename + is found. + + +.. module:: pygments.styles + +Functions from :mod:`pygments.styles`: + +.. function:: get_style_by_name(name) + + Return a style class by its short name. The names of the builtin styles + are listed in :data:`pygments.styles.STYLE_MAP`. + + Will raise :exc:`pygments.util.ClassNotFound` if no style of that name is + found. + +.. function:: get_all_styles() + + Return an iterable over all registered styles, yielding their names. + + .. versionadded:: 0.6 + + +.. module:: pygments.lexer + +Lexers +====== + +The base lexer class from which all lexers are derived is: + +.. class:: Lexer(**options) + + The constructor takes a \*\*keywords dictionary of options. + Every subclass must first process its own options and then call + the `Lexer` constructor, since it processes the `stripnl`, + `stripall` and `tabsize` options. + + An example looks like this: + + .. sourcecode:: python + + def __init__(self, **options): + self.compress = options.get('compress', '') + Lexer.__init__(self, **options) + + As these options must all be specifiable as strings (due to the + command line usage), there are various utility functions + available to help with that, see `Option processing`_. + + .. method:: get_tokens(text) + + This method is the basic interface of a lexer. It is called by + the `highlight()` function. It must process the text and return an + iterable of ``(tokentype, value)`` pairs from `text`. + + Normally, you don't need to override this method. The default + implementation processes the `stripnl`, `stripall` and `tabsize` + options and then yields all tokens from `get_tokens_unprocessed()`, + with the ``index`` dropped. + + .. method:: get_tokens_unprocessed(text) + + This method should process the text and return an iterable of + ``(index, tokentype, value)`` tuples where ``index`` is the starting + position of the token within the input text. + + This method must be overridden by subclasses. + + .. staticmethod:: analyse_text(text) + + A static method which is called for lexer guessing. It should analyse + the text and return a float in the range from ``0.0`` to ``1.0``. + If it returns ``0.0``, the lexer will not be selected as the most + probable one, if it returns ``1.0``, it will be selected immediately. + + .. note:: You don't have to add ``@staticmethod`` to the definition of + this method, this will be taken care of by the Lexer's metaclass. + + For a list of known tokens have a look at the :doc:`tokens` page. + + A lexer also can have the following attributes (in fact, they are mandatory + except `alias_filenames`) that are used by the builtin lookup mechanism. + + .. attribute:: name + + Full name for the lexer, in human-readable form. + + .. attribute:: aliases + + A list of short, unique identifiers that can be used to lookup + the lexer from a list, e.g. using `get_lexer_by_name()`. + + .. attribute:: filenames + + A list of `fnmatch` patterns that match filenames which contain + content for this lexer. The patterns in this list should be unique among + all lexers. + + .. attribute:: alias_filenames + + A list of `fnmatch` patterns that match filenames which may or may not + contain content for this lexer. This list is used by the + :func:`.guess_lexer_for_filename()` function, to determine which lexers + are then included in guessing the correct one. That means that + e.g. every lexer for HTML and a template language should include + ``\*.html`` in this list. + + .. attribute:: mimetypes + + A list of MIME types for content that can be lexed with this + lexer. + + +.. module:: pygments.formatter + +Formatters +========== + +A formatter is derived from this class: + + +.. class:: Formatter(**options) + + As with lexers, this constructor processes options and then must call the + base class :meth:`__init__`. + + The :class:`Formatter` class recognizes the options `style`, `full` and + `title`. It is up to the formatter class whether it uses them. + + .. method:: get_style_defs(arg='') + + This method must return statements or declarations suitable to define + the current style for subsequent highlighted text (e.g. CSS classes + in the `HTMLFormatter`). + + The optional argument `arg` can be used to modify the generation and + is formatter dependent (it is standardized because it can be given on + the command line). + + This method is called by the ``-S`` :doc:`command-line option `, + the `arg` is then given by the ``-a`` option. + + .. method:: format(tokensource, outfile) + + This method must format the tokens from the `tokensource` iterable and + write the formatted version to the file object `outfile`. + + Formatter options can control how exactly the tokens are converted. + + .. versionadded:: 0.7 + A formatter must have the following attributes that are used by the + builtin lookup mechanism. + + .. attribute:: name + + Full name for the formatter, in human-readable form. + + .. attribute:: aliases + + A list of short, unique identifiers that can be used to lookup + the formatter from a list, e.g. using :func:`.get_formatter_by_name()`. + + .. attribute:: filenames + + A list of :mod:`fnmatch` patterns that match filenames for which this + formatter can produce output. The patterns in this list should be unique + among all formatters. + + +.. module:: pygments.util + +Option processing +================= + +The :mod:`pygments.util` module has some utility functions usable for option +processing: + +.. exception:: OptionError + + This exception will be raised by all option processing functions if + the type or value of the argument is not correct. + +.. function:: get_bool_opt(options, optname, default=None) + + Interpret the key `optname` from the dictionary `options` as a boolean and + return it. Return `default` if `optname` is not in `options`. + + The valid string values for ``True`` are ``1``, ``yes``, ``true`` and + ``on``, the ones for ``False`` are ``0``, ``no``, ``false`` and ``off`` + (matched case-insensitively). + +.. function:: get_int_opt(options, optname, default=None) + + As :func:`get_bool_opt`, but interpret the value as an integer. + +.. function:: get_list_opt(options, optname, default=None) + + If the key `optname` from the dictionary `options` is a string, + split it at whitespace and return it. If it is already a list + or a tuple, it is returned as a list. + +.. function:: get_choice_opt(options, optname, allowed, default=None) + + If the key `optname` from the dictionary is not in the sequence + `allowed`, raise an error, otherwise return it. + + .. versionadded:: 0.8 diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/authors.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/authors.rst new file mode 100644 index 000000000..f8373f0a4 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/authors.rst @@ -0,0 +1,4 @@ +Full contributor list +===================== + +.. include:: ../../AUTHORS diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/changelog.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/changelog.rst new file mode 100644 index 000000000..f264cab0b --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/changelog.rst @@ -0,0 +1 @@ +.. include:: ../../CHANGES diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/cmdline.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/cmdline.rst new file mode 100644 index 000000000..bf0177a30 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/cmdline.rst @@ -0,0 +1,145 @@ +.. -*- mode: rst -*- + +====================== +Command Line Interface +====================== + +You can use Pygments from the shell, provided you installed the +:program:`pygmentize` script:: + + $ pygmentize test.py + print "Hello World" + +will print the file test.py to standard output, using the Python lexer +(inferred from the file name extension) and the terminal formatter (because +you didn't give an explicit formatter name). + +If you want HTML output:: + + $ pygmentize -f html -l python -o test.html test.py + +As you can see, the -l option explicitly selects a lexer. As seen above, if you +give an input file name and it has an extension that Pygments recognizes, you can +omit this option. + +The ``-o`` option gives an output file name. If it is not given, output is +written to stdout. + +The ``-f`` option selects a formatter (as with ``-l``, it can also be omitted +if an output file name is given and has a supported extension). +If no output file name is given and ``-f`` is omitted, the +:class:`.TerminalFormatter` is used. + +The above command could therefore also be given as:: + + $ pygmentize -o test.html test.py + +To create a full HTML document, including line numbers and stylesheet (using the +"emacs" style), highlighting the Python file ``test.py`` to ``test.html``:: + + $ pygmentize -O full,style=emacs -o test.html test.py + + +Options and filters +------------------- + +Lexer and formatter options can be given using the ``-O`` option:: + + $ pygmentize -f html -O style=colorful,linenos=1 -l python test.py + +Be sure to enclose the option string in quotes if it contains any special shell +characters, such as spaces or expansion wildcards like ``*``. If an option +expects a list value, separate the list entries with spaces (you'll have to +quote the option value in this case too, so that the shell doesn't split it). + +Since the ``-O`` option argument is split at commas and expects the split values +to be of the form ``name=value``, you can't give an option value that contains +commas or equals signs. Therefore, an option ``-P`` is provided (as of Pygments +0.9) that works like ``-O`` but can only pass one option per ``-P``. Its value +can then contain all characters:: + + $ pygmentize -P "heading=Pygments, the Python highlighter" ... + +Filters are added to the token stream using the ``-F`` option:: + + $ pygmentize -f html -l pascal -F keywordcase:case=upper main.pas + +As you see, options for the filter are given after a colon. As for ``-O``, the +filter name and options must be one shell word, so there may not be any spaces +around the colon. + + +Generating styles +----------------- + +Formatters normally don't output full style information. For example, the HTML +formatter by default only outputs ```` tags with ``class`` attributes. +Therefore, there's a special ``-S`` option for generating style definitions. +Usage is as follows:: + + $ pygmentize -f html -S colorful -a .syntax + +generates a CSS style sheet (because you selected the HTML formatter) for +the "colorful" style prepending a ".syntax" selector to all style rules. + +For an explanation what ``-a`` means for :doc:`a particular formatter +`, look for the `arg` argument for the formatter's +:meth:`.get_style_defs()` method. + + +Getting lexer names +------------------- + +.. versionadded:: 1.0 + +The ``-N`` option guesses a lexer name for a given filename, so that :: + + $ pygmentize -N setup.py + +will print out ``python``. It won't highlight anything yet. If no specific +lexer is known for that filename, ``text`` is printed. + + +Getting help +------------ + +The ``-L`` option lists lexers, formatters, along with their short +names and supported file name extensions, styles and filters. If you want to see +only one category, give it as an argument:: + + $ pygmentize -L filters + +will list only all installed filters. + +The ``-H`` option will give you detailed information (the same that can be found +in this documentation) about a lexer, formatter or filter. Usage is as follows:: + + $ pygmentize -H formatter html + +will print the help for the HTML formatter, while :: + + $ pygmentize -H lexer python + +will print the help for the Python lexer, etc. + + +A note on encodings +------------------- + +.. versionadded:: 0.9 + +Pygments tries to be smart regarding encodings in the formatting process: + +* If you give an ``encoding`` option, it will be used as the input and + output encoding. + +* If you give an ``outencoding`` option, it will override ``encoding`` + as the output encoding. + +* If you don't give an encoding and have given an output file, the default + encoding for lexer and formatter is ``latin1`` (which will pass through + all non-ASCII characters). + +* If you don't give an encoding and haven't given an output file (that means + output is written to the console), the default encoding for lexer and + formatter is the terminal encoding (``sys.stdout.encoding``). diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filterdevelopment.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filterdevelopment.rst new file mode 100644 index 000000000..bc399a6f4 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filterdevelopment.rst @@ -0,0 +1,70 @@ +.. -*- mode: rst -*- + +===================== +Write your own filter +===================== + +.. versionadded:: 0.7 + +Writing own filters is very easy. All you have to do is to subclass +the `Filter` class and override the `filter` method. Additionally a +filter is instanciated with some keyword arguments you can use to +adjust the behavior of your filter. + + +Subclassing Filters +=================== + +As an example, we write a filter that converts all `Name.Function` tokens +to normal `Name` tokens to make the output less colorful. + +.. sourcecode:: python + + from pygments.util import get_bool_opt + from pygments.token import Name + from pygments.filter import Filter + + class UncolorFilter(Filter): + + def __init__(self, **options): + Filter.__init__(self, **options) + self.class_too = get_bool_opt(options, 'classtoo') + + def filter(self, lexer, stream): + for ttype, value in stream: + if ttype is Name.Function or (self.class_too and + ttype is Name.Class): + ttype = Name + yield ttype, value + +Some notes on the `lexer` argument: that can be quite confusing since it doesn't +need to be a lexer instance. If a filter was added by using the `add_filter()` +function of lexers, that lexer is registered for the filter. In that case +`lexer` will refer to the lexer that has registered the filter. It *can* be used +to access options passed to a lexer. Because it could be `None` you always have +to check for that case if you access it. + + +Using a decorator +================= + +You can also use the `simplefilter` decorator from the `pygments.filter` module: + +.. sourcecode:: python + + from pygments.util import get_bool_opt + from pygments.token import Name + from pygments.filter import simplefilter + + + @simplefilter + def uncolor(lexer, stream, options): + class_too = get_bool_opt(options, 'classtoo') + for ttype, value in stream: + if ttype is Name.Function or (class_too and + ttype is Name.Class): + ttype = Name + yield ttype, value + +The decorator automatically subclasses an internal filter class and uses the +decorated function for filtering. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filters.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filters.rst new file mode 100644 index 000000000..ff2519a3e --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/filters.rst @@ -0,0 +1,41 @@ +.. -*- mode: rst -*- + +======= +Filters +======= + +.. versionadded:: 0.7 + +You can filter token streams coming from lexers to improve or annotate the +output. For example, you can highlight special words in comments, convert +keywords to upper or lowercase to enforce a style guide etc. + +To apply a filter, you can use the `add_filter()` method of a lexer: + +.. sourcecode:: pycon + + >>> from pygments.lexers import PythonLexer + >>> l = PythonLexer() + >>> # add a filter given by a string and options + >>> l.add_filter('codetagify', case='lower') + >>> l.filters + [] + >>> from pygments.filters import KeywordCaseFilter + >>> # or give an instance + >>> l.add_filter(KeywordCaseFilter(case='lower')) + +The `add_filter()` method takes keyword arguments which are forwarded to +the constructor of the filter. + +To get a list of all registered filters by name, you can use the +`get_all_filters()` function from the `pygments.filters` module that returns an +iterable for all known filters. + +If you want to write your own filter, have a look at :doc:`Write your own filter +`. + + +Builtin Filters +=============== + +.. pygmentsdoc:: filters diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatterdevelopment.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatterdevelopment.rst new file mode 100644 index 000000000..2bfac05c6 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatterdevelopment.rst @@ -0,0 +1,169 @@ +.. -*- mode: rst -*- + +======================== +Write your own formatter +======================== + +As well as creating :doc:`your own lexer `, writing a new +formatter for Pygments is easy and straightforward. + +A formatter is a class that is initialized with some keyword arguments (the +formatter options) and that must provides a `format()` method. +Additionally a formatter should provide a `get_style_defs()` method that +returns the style definitions from the style in a form usable for the +formatter's output format. + + +Quickstart +========== + +The most basic formatter shipped with Pygments is the `NullFormatter`. It just +sends the value of a token to the output stream: + +.. sourcecode:: python + + from pygments.formatter import Formatter + + class NullFormatter(Formatter): + def format(self, tokensource, outfile): + for ttype, value in tokensource: + outfile.write(value) + +As you can see, the `format()` method is passed two parameters: `tokensource` +and `outfile`. The first is an iterable of ``(token_type, value)`` tuples, +the latter a file like object with a `write()` method. + +Because the formatter is that basic it doesn't overwrite the `get_style_defs()` +method. + + +Styles +====== + +Styles aren't instantiated but their metaclass provides some class functions +so that you can access the style definitions easily. + +Styles are iterable and yield tuples in the form ``(ttype, d)`` where `ttype` +is a token and `d` is a dict with the following keys: + +``'color'`` + Hexadecimal color value (eg: ``'ff0000'`` for red) or `None` if not + defined. + +``'bold'`` + `True` if the value should be bold + +``'italic'`` + `True` if the value should be italic + +``'underline'`` + `True` if the value should be underlined + +``'bgcolor'`` + Hexadecimal color value for the background (eg: ``'eeeeeee'`` for light + gray) or `None` if not defined. + +``'border'`` + Hexadecimal color value for the border (eg: ``'0000aa'`` for a dark + blue) or `None` for no border. + +Additional keys might appear in the future, formatters should ignore all keys +they don't support. + + +HTML 3.2 Formatter +================== + +For an more complex example, let's implement a HTML 3.2 Formatter. We don't +use CSS but inline markup (````, ````, etc). Because this isn't good +style this formatter isn't in the standard library ;-) + +.. sourcecode:: python + + from pygments.formatter import Formatter + + class OldHtmlFormatter(Formatter): + + def __init__(self, **options): + Formatter.__init__(self, **options) + + # create a dict of (start, end) tuples that wrap the + # value of a token so that we can use it in the format + # method later + self.styles = {} + + # we iterate over the `_styles` attribute of a style item + # that contains the parsed style values. + for token, style in self.style: + start = end = '' + # a style item is a tuple in the following form: + # colors are readily specified in hex: 'RRGGBB' + if style['color']: + start += '' % style['color'] + end = '' + end + if style['bold']: + start += '' + end = '' + end + if style['italic']: + start += '' + end = '' + end + if style['underline']: + start += '' + end = '' + end + self.styles[token] = (start, end) + + def format(self, tokensource, outfile): + # lastval is a string we use for caching + # because it's possible that an lexer yields a number + # of consecutive tokens with the same token type. + # to minimize the size of the generated html markup we + # try to join the values of same-type tokens here + lastval = '' + lasttype = None + + # wrap the whole output with
    +            outfile.write('
    ')
    +
    +            for ttype, value in tokensource:
    +                # if the token type doesn't exist in the stylemap
    +                # we try it with the parent of the token type
    +                # eg: parent of Token.Literal.String.Double is
    +                # Token.Literal.String
    +                while ttype not in self.styles:
    +                    ttype = ttype.parent
    +                if ttype == lasttype:
    +                    # the current token type is the same of the last
    +                    # iteration. cache it
    +                    lastval += value
    +                else:
    +                    # not the same token as last iteration, but we
    +                    # have some data in the buffer. wrap it with the
    +                    # defined style and write it to the output file
    +                    if lastval:
    +                        stylebegin, styleend = self.styles[lasttype]
    +                        outfile.write(stylebegin + lastval + styleend)
    +                    # set lastval/lasttype to current values
    +                    lastval = value
    +                    lasttype = ttype
    +
    +            # if something is left in the buffer, write it to the
    +            # output file, then close the opened 
     tag
    +            if lastval:
    +                stylebegin, styleend = self.styles[lasttype]
    +                outfile.write(stylebegin + lastval + styleend)
    +            outfile.write('
    \n') + +The comments should explain it. Again, this formatter doesn't override the +`get_style_defs()` method. If we would have used CSS classes instead of +inline HTML markup, we would need to generate the CSS first. For that +purpose the `get_style_defs()` method exists: + + +Generating Style Definitions +============================ + +Some formatters like the `LatexFormatter` and the `HtmlFormatter` don't +output inline markup but reference either macros or css classes. Because +the definitions of those are not part of the output, the `get_style_defs()` +method exists. It is passed one parameter (if it's used and how it's used +is up to the formatter) and has to return a string or ``None``. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatters.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatters.rst new file mode 100644 index 000000000..9e7074e81 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/formatters.rst @@ -0,0 +1,48 @@ +.. -*- mode: rst -*- + +==================== +Available formatters +==================== + +This page lists all builtin formatters. + +Common options +============== + +All formatters support these options: + +`encoding` + If given, must be an encoding name (such as ``"utf-8"``). This will + be used to convert the token strings (which are Unicode strings) + to byte strings in the output (default: ``None``). + It will also be written in an encoding declaration suitable for the + document format if the `full` option is given (e.g. a ``meta + content-type`` directive in HTML or an invocation of the `inputenc` + package in LaTeX). + + If this is ``""`` or ``None``, Unicode strings will be written + to the output file, which most file-like objects do not support. + For example, `pygments.highlight()` will return a Unicode string if + called with no `outfile` argument and a formatter that has `encoding` + set to ``None`` because it uses a `StringIO.StringIO` object that + supports Unicode arguments to `write()`. Using a regular file object + wouldn't work. + + .. versionadded:: 0.6 + +`outencoding` + When using Pygments from the command line, any `encoding` option given is + passed to the lexer and the formatter. This is sometimes not desirable, + for example if you want to set the input encoding to ``"guess"``. + Therefore, `outencoding` has been introduced which overrides `encoding` + for the formatter if given. + + .. versionadded:: 0.7 + + +Formatter classes +================= + +All these classes are importable from :mod:`pygments.formatters`. + +.. pygmentsdoc:: formatters diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/index.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/index.rst new file mode 100644 index 000000000..30d5c0851 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/index.rst @@ -0,0 +1,66 @@ +Pygments documentation +====================== + +**Starting with Pygments** + +.. toctree:: + :maxdepth: 1 + + ../download + quickstart + cmdline + +**Builtin components** + +.. toctree:: + :maxdepth: 1 + + lexers + filters + formatters + styles + +**Reference** + +.. toctree:: + :maxdepth: 1 + + unicode + tokens + api + +**Hacking for Pygments** + +.. toctree:: + :maxdepth: 1 + + lexerdevelopment + formatterdevelopment + filterdevelopment + plugins + +**Hints and tricks** + +.. toctree:: + :maxdepth: 1 + + rstdirective + moinmoin + java + integrate + +**About Pygments** + +.. toctree:: + :maxdepth: 1 + + changelog + authors + + +If you find bugs or have suggestions for the documentation, please look +:ref:`here ` for info on how to contact the team. + +.. XXX You can download an offline version of this documentation from the + :doc:`download page `. + diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/integrate.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/integrate.rst new file mode 100644 index 000000000..03fc268ff --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/integrate.rst @@ -0,0 +1,44 @@ +.. -*- mode: rst -*- + +=================================== +Using Pygments in various scenarios +=================================== + +PyGtk +----- + +Armin has written a piece of sample code that shows how to create a Gtk +`TextBuffer` object containing Pygments-highlighted text. + +See the article here: http://lucumr.pocoo.org/cogitations/2007/05/30/pygments-gtk-rendering/ + +Wordpress +--------- + +He also has a snippet that shows how to use Pygments in WordPress: + +http://lucumr.pocoo.org/cogitations/2007/05/30/pygments-in-wordpress/ + +Markdown +-------- + +Since Pygments 0.9, the distribution ships Markdown_ preprocessor sample code +that uses Pygments to render source code in +:file:`external/markdown-processor.py`. You can copy and adapt it to your +liking. + +.. _Markdown: http://www.freewisdom.org/projects/python-markdown/ + +TextMate +-------- + +Antonio Cangiano has created a Pygments bundle for TextMate that allows to +colorize code via a simple menu option. It can be found here_. + +.. _here: http://antoniocangiano.com/2008/10/28/pygments-textmate-bundle/ + +Bash completion +--------------- + +The source distribution contains a file ``external/pygments.bashcomp`` that +sets up completion for the ``pygmentize`` command in bash. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/java.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/java.rst new file mode 100644 index 000000000..5eb6196a1 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/java.rst @@ -0,0 +1,70 @@ +===================== +Use Pygments in Java +===================== + +Thanks to `Jython `__ it is possible to use Pygments in +Java. + +This page is a simple tutorial to get an idea of how this is working. You can +then look at the `Jython documentation `__ for more +advanced use. + +Since version 1.5, Pygments is deployed on `Maven Central +`__ as a JAR so is Jython +which makes it a lot easier to create the Java project. + +Here is an example of a `Maven `__ ``pom.xml`` file for a +project running Pygments: + +.. sourcecode:: xml + + + + + 4.0.0 + example + example + 1.0-SNAPSHOT + + + org.python + jython-standalone + 2.5.3 + + + org.pygments + pygments + 1.5 + runtime + + + + +The following Java example: + +.. sourcecode:: java + + PythonInterpreter interpreter = new PythonInterpreter(); + + // Set a variable with the content you want to work with + interpreter.set("code", code); + + // Simple use Pygments as you would in Python + interpreter.exec("from pygments import highlight\n" + + "from pygments.lexers import PythonLexer\n" + + "from pygments.formatters import HtmlFormatter\n" + + "\nresult = highlight(code, PythonLexer(), HtmlFormatter())"); + + // Get the result that has been set in a variable + System.out.println(interpreter.get("result", String.class)); + +will print something like: + +.. sourcecode:: html + +
    +
    print "Hello World"
    +
    diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexerdevelopment.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexerdevelopment.rst new file mode 100644 index 000000000..eab1306af --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexerdevelopment.rst @@ -0,0 +1,602 @@ +.. -*- mode: rst -*- + +==================== +Write your own lexer +==================== + +If a lexer for your favorite language is missing in the Pygments package, you can +easily write your own and extend Pygments. + +All you need can be found inside the :mod:`pygments.lexer` module. As you can +read in the :doc:`API documentation `, a lexer is a class that is +initialized with some keyword arguments (the lexer options) and that provides a +:meth:`.get_tokens_unprocessed()` method which is given a string or unicode +object with the data to parse. + +The :meth:`.get_tokens_unprocessed()` method must return an iterator or iterable +containing tuples in the form ``(index, token, value)``. Normally you don't need +to do this since there are numerous base lexers you can subclass. + + +RegexLexer +========== + +A very powerful (but quite easy to use) lexer is the :class:`RegexLexer`. This +lexer base class allows you to define lexing rules in terms of *regular +expressions* for different *states*. + +States are groups of regular expressions that are matched against the input +string at the *current position*. If one of these expressions matches, a +corresponding action is performed (normally yielding a token with a specific +type), the current position is set to where the last match ended and the +matching process continues with the first regex of the current state. + +Lexer states are kept in a state stack: each time a new state is entered, the +new state is pushed onto the stack. The most basic lexers (like the +`DiffLexer`) just need one state. + +Each state is defined as a list of tuples in the form (`regex`, `action`, +`new_state`) where the last item is optional. In the most basic form, `action` +is a token type (like `Name.Builtin`). That means: When `regex` matches, emit a +token with the match text and type `tokentype` and push `new_state` on the state +stack. If the new state is ``'#pop'``, the topmost state is popped from the +stack instead. (To pop more than one state, use ``'#pop:2'`` and so on.) +``'#push'`` is a synonym for pushing the current state on the +stack. + +The following example shows the `DiffLexer` from the builtin lexers. Note that +it contains some additional attributes `name`, `aliases` and `filenames` which +aren't required for a lexer. They are used by the builtin lexer lookup +functions. + +.. sourcecode:: python + + from pygments.lexer import RegexLexer + from pygments.token import * + + class DiffLexer(RegexLexer): + name = 'Diff' + aliases = ['diff'] + filenames = ['*.diff'] + + tokens = { + 'root': [ + (r' .*\n', Text), + (r'\+.*\n', Generic.Inserted), + (r'-.*\n', Generic.Deleted), + (r'@.*\n', Generic.Subheading), + (r'Index.*\n', Generic.Heading), + (r'=.*\n', Generic.Heading), + (r'.*\n', Text), + ] + } + +As you can see this lexer only uses one state. When the lexer starts scanning +the text, it first checks if the current character is a space. If this is true +it scans everything until newline and returns the parsed data as `Text` token. + +If this rule doesn't match, it checks if the current char is a plus sign. And +so on. + +If no rule matches at the current position, the current char is emitted as an +`Error` token that indicates a parsing error, and the position is increased by +1. + + +Adding and testing a new lexer +============================== + +To make pygments aware of your new lexer, you have to perform the following +steps: + +First, change to the current directory containing the pygments source code: + +.. sourcecode:: console + + $ cd .../pygments-main + +Next, make sure the lexer is known from outside of the module. All modules in +the ``pygments.lexers`` specify ``__all__``. For example, ``other.py`` sets: + +.. sourcecode:: python + + __all__ = ['BrainfuckLexer', 'BefungeLexer', ...] + +Simply add the name of your lexer class to this list. + +Finally the lexer can be made publically known by rebuilding the lexer +mapping: + +.. sourcecode:: console + + $ make mapfiles + +To test the new lexer, store an example file with the proper extension in +``tests/examplefiles``. For example, to test your ``DiffLexer``, add a +``tests/examplefiles/example.diff`` containing a sample diff output. + +Now you can use pygmentize to render your example to HTML: + +.. sourcecode:: console + + $ ./pygmentize -O full -f html -o /tmp/example.html tests/examplefiles/example.diff + +Note that this explicitely calls the ``pygmentize`` in the current directory +by preceding it with ``./``. This ensures your modifications are used. +Otherwise a possibly already installed, unmodified version without your new +lexer would have been called from the system search path (``$PATH``). + +To view the result, open ``/tmp/example.html`` in your browser. + +Once the example renders as expected, you should run the complete test suite: + +.. sourcecode:: console + + $ make test + + +Regex Flags +=========== + +You can either define regex flags in the regex (``r'(?x)foo bar'``) or by adding +a `flags` attribute to your lexer class. If no attribute is defined, it defaults +to `re.MULTILINE`. For more informations about regular expression flags see the +`regular expressions`_ help page in the python documentation. + +.. _regular expressions: http://docs.python.org/lib/re-syntax.html + + +Scanning multiple tokens at once +================================ + +Here is a more complex lexer that highlights INI files. INI files consist of +sections, comments and key = value pairs: + +.. sourcecode:: python + + from pygments.lexer import RegexLexer, bygroups + from pygments.token import * + + class IniLexer(RegexLexer): + name = 'INI' + aliases = ['ini', 'cfg'] + filenames = ['*.ini', '*.cfg'] + + tokens = { + 'root': [ + (r'\s+', Text), + (r';.*?$', Comment), + (r'\[.*?\]$', Keyword), + (r'(.*?)(\s*)(=)(\s*)(.*?)$', + bygroups(Name.Attribute, Text, Operator, Text, String)) + ] + } + +The lexer first looks for whitespace, comments and section names. And later it +looks for a line that looks like a key, value pair, separated by an ``'='`` +sign, and optional whitespace. + +The `bygroups` helper makes sure that each group is yielded with a different +token type. First the `Name.Attribute` token, then a `Text` token for the +optional whitespace, after that a `Operator` token for the equals sign. Then a +`Text` token for the whitespace again. The rest of the line is returned as +`String`. + +Note that for this to work, every part of the match must be inside a capturing +group (a ``(...)``), and there must not be any nested capturing groups. If you +nevertheless need a group, use a non-capturing group defined using this syntax: +``r'(?:some|words|here)'`` (note the ``?:`` after the beginning parenthesis). + +If you find yourself needing a capturing group inside the regex which +shouldn't be part of the output but is used in the regular expressions for +backreferencing (eg: ``r'(<(foo|bar)>)(.*?)()'``), you can pass `None` +to the bygroups function and it will skip that group will be skipped in the +output. + + +Changing states +=============== + +Many lexers need multiple states to work as expected. For example, some +languages allow multiline comments to be nested. Since this is a recursive +pattern it's impossible to lex just using regular expressions. + +Here is the solution: + +.. sourcecode:: python + + from pygments.lexer import RegexLexer + from pygments.token import * + + class ExampleLexer(RegexLexer): + name = 'Example Lexer with states' + + tokens = { + 'root': [ + (r'[^/]+', Text), + (r'/\*', Comment.Multiline, 'comment'), + (r'//.*?$', Comment.Singleline), + (r'/', Text) + ], + 'comment': [ + (r'[^*/]', Comment.Multiline), + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'[*/]', Comment.Multiline) + ] + } + +This lexer starts lexing in the ``'root'`` state. It tries to match as much as +possible until it finds a slash (``'/'``). If the next character after the slash +is a star (``'*'``) the `RegexLexer` sends those two characters to the output +stream marked as `Comment.Multiline` and continues parsing with the rules +defined in the ``'comment'`` state. + +If there wasn't a star after the slash, the `RegexLexer` checks if it's a +singleline comment (eg: followed by a second slash). If this also wasn't the +case it must be a single slash (the separate regex for a single slash must also +be given, else the slash would be marked as an error token). + +Inside the ``'comment'`` state, we do the same thing again. Scan until the lexer +finds a star or slash. If it's the opening of a multiline comment, push the +``'comment'`` state on the stack and continue scanning, again in the +``'comment'`` state. Else, check if it's the end of the multiline comment. If +yes, pop one state from the stack. + +Note: If you pop from an empty stack you'll get an `IndexError`. (There is an +easy way to prevent this from happening: don't ``'#pop'`` in the root state). + +If the `RegexLexer` encounters a newline that is flagged as an error token, the +stack is emptied and the lexer continues scanning in the ``'root'`` state. This +helps producing error-tolerant highlighting for erroneous input, e.g. when a +single-line string is not closed. + + +Advanced state tricks +===================== + +There are a few more things you can do with states: + +- You can push multiple states onto the stack if you give a tuple instead of a + simple string as the third item in a rule tuple. For example, if you want to + match a comment containing a directive, something like:: + + /* rest of comment */ + + you can use this rule: + + .. sourcecode:: python + + tokens = { + 'root': [ + (r'/\* <', Comment, ('comment', 'directive')), + ... + ], + 'directive': [ + (r'[^>]*', Comment.Directive), + (r'>', Comment, '#pop'), + ], + 'comment': [ + (r'[^*]+', Comment), + (r'\*/', Comment, '#pop'), + (r'\*', Comment), + ] + } + + When this encounters the above sample, first ``'comment'`` and ``'directive'`` + are pushed onto the stack, then the lexer continues in the directive state + until it finds the closing ``>``, then it continues in the comment state until + the closing ``*/``. Then, both states are popped from the stack again and + lexing continues in the root state. + + .. versionadded:: 0.9 + The tuple can contain the special ``'#push'`` and ``'#pop'`` (but not + ``'#pop:n'``) directives. + + +- You can include the rules of a state in the definition of another. This is + done by using `include` from `pygments.lexer`: + + .. sourcecode:: python + + from pygments.lexer import RegexLexer, bygroups, include + from pygments.token import * + + class ExampleLexer(RegexLexer): + tokens = { + 'comments': [ + (r'/\*.*?\*/', Comment), + (r'//.*?\n', Comment), + ], + 'root': [ + include('comments'), + (r'(function )(\w+)( {)', + bygroups(Keyword, Name, Keyword), 'function'), + (r'.', Text), + ], + 'function': [ + (r'[^}/]+', Text), + include('comments'), + (r'/', Text), + (r'}', Keyword, '#pop'), + ] + } + + This is a hypothetical lexer for a language that consist of functions and + comments. Because comments can occur at toplevel and in functions, we need + rules for comments in both states. As you can see, the `include` helper saves + repeating rules that occur more than once (in this example, the state + ``'comment'`` will never be entered by the lexer, as it's only there to be + included in ``'root'`` and ``'function'``). + + +- Sometimes, you may want to "combine" a state from existing ones. This is + possible with the `combine` helper from `pygments.lexer`. + + If you, instead of a new state, write ``combined('state1', 'state2')`` as the + third item of a rule tuple, a new anonymous state will be formed from state1 + and state2 and if the rule matches, the lexer will enter this state. + + This is not used very often, but can be helpful in some cases, such as the + `PythonLexer`'s string literal processing. + +- If you want your lexer to start lexing in a different state you can modify + the stack by overloading the `get_tokens_unprocessed()` method: + + .. sourcecode:: python + + from pygments.lexer import RegexLexer + + class MyLexer(RegexLexer): + tokens = {...} + + def get_tokens_unprocessed(self, text): + stack = ['root', 'otherstate'] + for item in RegexLexer.get_tokens_unprocessed(text, stack): + yield item + + Some lexers like the `PhpLexer` use this to make the leading ``', Name.Tag), + ], + 'script-content': [ + (r'(.+?)(<\s*/\s*script\s*>)', + bygroups(using(JavascriptLexer), Name.Tag), + '#pop'), + ] + } + +Here the content of a ```` end tag is processed by the `JavascriptLexer`, while the +end tag is yielded as a normal token with the `Name.Tag` type. + +As an additional goodie, if the lexer class is replaced by `this` (imported from +`pygments.lexer`), the "other" lexer will be the current one (because you cannot +refer to the current class within the code that runs at class definition time). + +Also note the ``(r'<\s*script\s*', Name.Tag, ('script-content', 'tag'))`` rule. +Here, two states are pushed onto the state stack, ``'script-content'`` and +``'tag'``. That means that first ``'tag'`` is processed, which will parse +attributes and the closing ``>``, then the ``'tag'`` state is popped and the +next state on top of the stack will be ``'script-content'``. + +The `using()` helper has a special keyword argument, `state`, which works as +follows: if given, the lexer to use initially is not in the ``"root"`` state, +but in the state given by this argument. This *only* works with a `RegexLexer`. + +Any other keywords arguments passed to `using()` are added to the keyword +arguments used to create the lexer. + + +Delegating Lexer +================ + +Another approach for nested lexers is the `DelegatingLexer` which is for +example used for the template engine lexers. It takes two lexers as +arguments on initialisation: a `root_lexer` and a `language_lexer`. + +The input is processed as follows: First, the whole text is lexed with the +`language_lexer`. All tokens yielded with a type of ``Other`` are then +concatenated and given to the `root_lexer`. The language tokens of the +`language_lexer` are then inserted into the `root_lexer`'s token stream +at the appropriate positions. + +.. sourcecode:: python + + from pygments.lexer import DelegatingLexer + from pygments.lexers.web import HtmlLexer, PhpLexer + + class HtmlPhpLexer(DelegatingLexer): + def __init__(self, **options): + super(HtmlPhpLexer, self).__init__(HtmlLexer, PhpLexer, **options) + +This procedure ensures that e.g. HTML with template tags in it is highlighted +correctly even if the template tags are put into HTML tags or attributes. + +If you want to change the needle token ``Other`` to something else, you can +give the lexer another token type as the third parameter: + +.. sourcecode:: python + + DelegatingLexer.__init__(MyLexer, OtherLexer, Text, **options) + + +Callbacks +========= + +Sometimes the grammar of a language is so complex that a lexer would be unable +to parse it just by using regular expressions and stacks. + +For this, the `RegexLexer` allows callbacks to be given in rule tuples, instead +of token types (`bygroups` and `using` are nothing else but preimplemented +callbacks). The callback must be a function taking two arguments: + +* the lexer itself +* the match object for the last matched rule + +The callback must then return an iterable of (or simply yield) ``(index, +tokentype, value)`` tuples, which are then just passed through by +`get_tokens_unprocessed()`. The ``index`` here is the position of the token in +the input string, ``tokentype`` is the normal token type (like `Name.Builtin`), +and ``value`` the associated part of the input string. + +You can see an example here: + +.. sourcecode:: python + + from pygments.lexer import RegexLexer + from pygments.token import Generic + + class HypotheticLexer(RegexLexer): + + def headline_callback(lexer, match): + equal_signs = match.group(1) + text = match.group(2) + yield match.start(), Generic.Headline, equal_signs + text + equal_signs + + tokens = { + 'root': [ + (r'(=+)(.*?)(\1)', headline_callback) + ] + } + +If the regex for the `headline_callback` matches, the function is called with the +match object. Note that after the callback is done, processing continues +normally, that is, after the end of the previous match. The callback has no +possibility to influence the position. + +There are not really any simple examples for lexer callbacks, but you can see +them in action e.g. in the `compiled.py`_ source code in the `CLexer` and +`JavaLexer` classes. + +.. _compiled.py: http://bitbucket.org/birkenfeld/pygments-main/src/tip/pygments/lexers/compiled.py + + +The ExtendedRegexLexer class +============================ + +The `RegexLexer`, even with callbacks, unfortunately isn't powerful enough for +the funky syntax rules of some languages that will go unnamed, such as Ruby. + +But fear not; even then you don't have to abandon the regular expression +approach. For Pygments has a subclass of `RegexLexer`, the `ExtendedRegexLexer`. +All features known from RegexLexers are available here too, and the tokens are +specified in exactly the same way, *except* for one detail: + +The `get_tokens_unprocessed()` method holds its internal state data not as local +variables, but in an instance of the `pygments.lexer.LexerContext` class, and +that instance is passed to callbacks as a third argument. This means that you +can modify the lexer state in callbacks. + +The `LexerContext` class has the following members: + +* `text` -- the input text +* `pos` -- the current starting position that is used for matching regexes +* `stack` -- a list containing the state stack +* `end` -- the maximum position to which regexes are matched, this defaults to + the length of `text` + +Additionally, the `get_tokens_unprocessed()` method can be given a +`LexerContext` instead of a string and will then process this context instead of +creating a new one for the string argument. + +Note that because you can set the current position to anything in the callback, +it won't be automatically be set by the caller after the callback is finished. +For example, this is how the hypothetical lexer above would be written with the +`ExtendedRegexLexer`: + +.. sourcecode:: python + + from pygments.lexer import ExtendedRegexLexer + from pygments.token import Generic + + class ExHypotheticLexer(ExtendedRegexLexer): + + def headline_callback(lexer, match, ctx): + equal_signs = match.group(1) + text = match.group(2) + yield match.start(), Generic.Headline, equal_signs + text + equal_signs + ctx.pos = match.end() + + tokens = { + 'root': [ + (r'(=+)(.*?)(\1)', headline_callback) + ] + } + +This might sound confusing (and it can really be). But it is needed, and for an +example look at the Ruby lexer in `agile.py`_. + +.. _agile.py: https://bitbucket.org/birkenfeld/pygments-main/src/tip/pygments/lexers/agile.py + + +Filtering Token Streams +======================= + +Some languages ship a lot of builtin functions (for example PHP). The total +amount of those functions differs from system to system because not everybody +has every extension installed. In the case of PHP there are over 3000 builtin +functions. That's an incredible huge amount of functions, much more than you +can put into a regular expression. + +But because only `Name` tokens can be function names it's solvable by overriding +the ``get_tokens_unprocessed()`` method. The following lexer subclasses the +`PythonLexer` so that it highlights some additional names as pseudo keywords: + +.. sourcecode:: python + + from pygments.lexers.agile import PythonLexer + from pygments.token import Name, Keyword + + class MyPythonLexer(PythonLexer): + EXTRA_KEYWORDS = ['foo', 'bar', 'foobar', 'barfoo', 'spam', 'eggs'] + + def get_tokens_unprocessed(self, text): + for index, token, value in PythonLexer.get_tokens_unprocessed(self, text): + if token is Name and value in self.EXTRA_KEYWORDS: + yield index, Keyword.Pseudo, value + else: + yield index, token, value + +The `PhpLexer` and `LuaLexer` use this method to resolve builtin functions. + +.. note:: Do not confuse this with the :doc:`filter ` system. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexers.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexers.rst new file mode 100644 index 000000000..914b53ef7 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/lexers.rst @@ -0,0 +1,69 @@ +.. -*- mode: rst -*- + +================ +Available lexers +================ + +This page lists all available builtin lexers and the options they take. + +Currently, **all lexers** support these options: + +`stripnl` + Strip leading and trailing newlines from the input (default: ``True``) + +`stripall` + Strip all leading and trailing whitespace from the input (default: + ``False``). + +`ensurenl` + Make sure that the input ends with a newline (default: ``True``). This + is required for some lexers that consume input linewise. + + .. versionadded:: 1.3 + +`tabsize` + If given and greater than 0, expand tabs in the input (default: ``0``). + +`encoding` + If given, must be an encoding name (such as ``"utf-8"``). This encoding + will be used to convert the input string to Unicode (if it is not already + a Unicode string). The default is ``"latin1"``. + + If this option is set to ``"guess"``, a simple UTF-8 vs. Latin-1 + detection is used, if it is set to ``"chardet"``, the + `chardet library `__ is used to + guess the encoding of the input. + + .. versionadded:: 0.6 + + +The "Short Names" field lists the identifiers that can be used with the +`get_lexer_by_name()` function. + +These lexers are builtin and can be imported from `pygments.lexers`: + +.. pygmentsdoc:: lexers + + +Iterating over all lexers +------------------------- + +.. versionadded:: 0.6 + +To get all lexers (both the builtin and the plugin ones), you can +use the `get_all_lexers()` function from the `pygments.lexers` +module: + +.. sourcecode:: pycon + + >>> from pygments.lexers import get_all_lexers + >>> i = get_all_lexers() + >>> i.next() + ('Diff', ('diff',), ('*.diff', '*.patch'), ('text/x-diff', 'text/x-patch')) + >>> i.next() + ('Delphi', ('delphi', 'objectpascal', 'pas', 'pascal'), ('*.pas',), ('text/x-pascal',)) + >>> i.next() + ('XML+Ruby', ('xml+erb', 'xml+ruby'), (), ()) + +As you can see, the return value is an iterator which yields tuples +in the form ``(name, aliases, filetypes, mimetypes)``. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/moinmoin.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/moinmoin.rst new file mode 100644 index 000000000..8b2216b3c --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/moinmoin.rst @@ -0,0 +1,39 @@ +.. -*- mode: rst -*- + +============================ +Using Pygments with MoinMoin +============================ + +From Pygments 0.7, the source distribution ships a `Moin`_ parser plugin that +can be used to get Pygments highlighting in Moin wiki pages. + +To use it, copy the file `external/moin-parser.py` from the Pygments +distribution to the `data/plugin/parser` subdirectory of your Moin instance. +Edit the options at the top of the file (currently ``ATTACHMENTS`` and +``INLINESTYLES``) and rename the file to the name that the parser directive +should have. For example, if you name the file ``code.py``, you can get a +highlighted Python code sample with this Wiki markup:: + + {{{ + #!code python + [...] + }}} + +where ``python`` is the Pygments name of the lexer to use. + +Additionally, if you set the ``ATTACHMENTS`` option to True, Pygments will also +be called for all attachments for whose filenames there is no other parser +registered. + +You are responsible for including CSS rules that will map the Pygments CSS +classes to colors. You can output a stylesheet file with `pygmentize`, put it +into the `htdocs` directory of your Moin instance and then include it in the +`stylesheets` configuration option in the Moin config, e.g.:: + + stylesheets = [('screen', '/htdocs/pygments.css')] + +If you do not want to do that and are willing to accept larger HTML output, you +can set the ``INLINESTYLES`` option to True. + + +.. _Moin: http://moinmoin.wikiwikiweb.de/ diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/plugins.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/plugins.rst new file mode 100644 index 000000000..a6f8d7b00 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/plugins.rst @@ -0,0 +1,93 @@ +================ +Register Plugins +================ + +If you want to extend Pygments without hacking the sources, but want to +use the lexer/formatter/style/filter lookup functions (`lexers.get_lexer_by_name` +et al.), you can use `setuptools`_ entrypoints to add new lexers, formatters +or styles as if they were in the Pygments core. + +.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools + +That means you can use your highlighter modules with the `pygmentize` script, +which relies on the mentioned functions. + + +Entrypoints +=========== + +Here is a list of setuptools entrypoints that Pygments understands: + +`pygments.lexers` + + This entrypoint is used for adding new lexers to the Pygments core. + The name of the entrypoint values doesn't really matter, Pygments extracts + required metadata from the class definition: + + .. sourcecode:: ini + + [pygments.lexers] + yourlexer = yourmodule:YourLexer + + Note that you have to define ``name``, ``aliases`` and ``filename`` + attributes so that you can use the highlighter from the command line: + + .. sourcecode:: python + + class YourLexer(...): + name = 'Name Of Your Lexer' + aliases = ['alias'] + filenames = ['*.ext'] + + +`pygments.formatters` + + You can use this entrypoint to add new formatters to Pygments. The + name of an entrypoint item is the name of the formatter. If you + prefix the name with a slash it's used as a filename pattern: + + .. sourcecode:: ini + + [pygments.formatters] + yourformatter = yourmodule:YourFormatter + /.ext = yourmodule:YourFormatter + + +`pygments.styles` + + To add a new style you can use this entrypoint. The name of the entrypoint + is the name of the style: + + .. sourcecode:: ini + + [pygments.styles] + yourstyle = yourmodule:YourStyle + + +`pygments.filters` + + Use this entrypoint to register a new filter. The name of the + entrypoint is the name of the filter: + + .. sourcecode:: ini + + [pygments.filters] + yourfilter = yourmodule:YourFilter + + +How To Use Entrypoints +====================== + +This documentation doesn't explain how to use those entrypoints because this is +covered in the `setuptools documentation`_. That page should cover everything +you need to write a plugin. + +.. _setuptools documentation: http://peak.telecommunity.com/DevCenter/setuptools + + +Extending The Core +================== + +If you have written a Pygments plugin that is open source, please inform us +about that. There is a high chance that we'll add it to the Pygments +distribution. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/quickstart.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/quickstart.rst new file mode 100644 index 000000000..dba7698a7 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/quickstart.rst @@ -0,0 +1,205 @@ +.. -*- mode: rst -*- + +=========================== +Introduction and Quickstart +=========================== + + +Welcome to Pygments! This document explains the basic concepts and terms and +gives a few examples of how to use the library. + + +Architecture +============ + +There are four types of components that work together highlighting a piece of +code: + +* A **lexer** splits the source into tokens, fragments of the source that + have a token type that determines what the text represents semantically + (e.g., keyword, string, or comment). There is a lexer for every language + or markup format that Pygments supports. +* The token stream can be piped through **filters**, which usually modify + the token types or text fragments, e.g. uppercasing all keywords. +* A **formatter** then takes the token stream and writes it to an output + file, in a format such as HTML, LaTeX or RTF. +* While writing the output, a **style** determines how to highlight all the + different token types. It maps them to attributes like "red and bold". + + +Example +======= + +Here is a small example for highlighting Python code: + +.. sourcecode:: python + + from pygments import highlight + from pygments.lexers import PythonLexer + from pygments.formatters import HtmlFormatter + + code = 'print "Hello World"' + print highlight(code, PythonLexer(), HtmlFormatter()) + +which prints something like this: + +.. sourcecode:: html + +
    +
    print "Hello World"
    +
    + +As you can see, Pygments uses CSS classes (by default, but you can change that) +instead of inline styles in order to avoid outputting redundant style information over +and over. A CSS stylesheet that contains all CSS classes possibly used in the output +can be produced by: + +.. sourcecode:: python + + print HtmlFormatter().get_style_defs('.highlight') + +The argument to :func:`get_style_defs` is used as an additional CSS selector: +the output may look like this: + +.. sourcecode:: css + + .highlight .k { color: #AA22FF; font-weight: bold } + .highlight .s { color: #BB4444 } + ... + + +Options +======= + +The :func:`highlight()` function supports a fourth argument called *outfile*, it +must be a file object if given. The formatted output will then be written to +this file instead of being returned as a string. + +Lexers and formatters both support options. They are given to them as keyword +arguments either to the class or to the lookup method: + +.. sourcecode:: python + + from pygments import highlight + from pygments.lexers import get_lexer_by_name + from pygments.formatters import HtmlFormatter + + lexer = get_lexer_by_name("python", stripall=True) + formatter = HtmlFormatter(linenos=True, cssclass="source") + result = highlight(code, lexer, formatter) + +This makes the lexer strip all leading and trailing whitespace from the input +(`stripall` option), lets the formatter output line numbers (`linenos` option), +and sets the wrapping ``
    ``'s class to ``source`` (instead of +``highlight``). + +Important options include: + +`encoding` : for lexers and formatters + Since Pygments uses Unicode strings internally, this determines which + encoding will be used to convert to or from byte strings. +`style` : for formatters + The name of the style to use when writing the output. + + +For an overview of builtin lexers and formatters and their options, visit the +:doc:`lexer ` and :doc:`formatters ` lists. + +For a documentation on filters, see :doc:`this page `. + + +Lexer and formatter lookup +========================== + +If you want to lookup a built-in lexer by its alias or a filename, you can use +one of the following methods: + +.. sourcecode:: pycon + + >>> from pygments.lexers import (get_lexer_by_name, + ... get_lexer_for_filename, get_lexer_for_mimetype) + + >>> get_lexer_by_name('python') + + + >>> get_lexer_for_filename('spam.rb') + + + >>> get_lexer_for_mimetype('text/x-perl') + + +All these functions accept keyword arguments; they will be passed to the lexer +as options. + +A similar API is available for formatters: use :func:`.get_formatter_by_name()` +and :func:`.get_formatter_for_filename()` from the :mod:`pygments.formatters` +module for this purpose. + + +Guessing lexers +=============== + +If you don't know the content of the file, or you want to highlight a file +whose extension is ambiguous, such as ``.html`` (which could contain plain HTML +or some template tags), use these functions: + +.. sourcecode:: pycon + + >>> from pygments.lexers import guess_lexer, guess_lexer_for_filename + + >>> guess_lexer('#!/usr/bin/python\nprint "Hello World!"') + + + >>> guess_lexer_for_filename('test.py', 'print "Hello World!"') + + +:func:`.guess_lexer()` passes the given content to the lexer classes' +:meth:`analyse_text()` method and returns the one for which it returns the +highest number. + +All lexers have two different filename pattern lists: the primary and the +secondary one. The :func:`.get_lexer_for_filename()` function only uses the +primary list, whose entries are supposed to be unique among all lexers. +:func:`.guess_lexer_for_filename()`, however, will first loop through all lexers +and look at the primary and secondary filename patterns if the filename matches. +If only one lexer matches, it is returned, else the guessing mechanism of +:func:`.guess_lexer()` is used with the matching lexers. + +As usual, keyword arguments to these functions are given to the created lexer +as options. + + +Command line usage +================== + +You can use Pygments from the command line, using the :program:`pygmentize` +script:: + + $ pygmentize test.py + +will highlight the Python file test.py using ANSI escape sequences +(a.k.a. terminal colors) and print the result to standard output. + +To output HTML, use the ``-f`` option:: + + $ pygmentize -f html -o test.html test.py + +to write an HTML-highlighted version of test.py to the file test.html. +Note that it will only be a snippet of HTML, if you want a full HTML document, +use the "full" option:: + + $ pygmentize -f html -O full -o test.html test.py + +This will produce a full HTML document with included stylesheet. + +A style can be selected with ``-O style=``. + +If you need a stylesheet for an existing HTML file using Pygments CSS classes, +it can be created with:: + + $ pygmentize -S default -f html > style.css + +where ``default`` is the style name. + +More options and tricks and be found in the :doc:`command line reference +`. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/rstdirective.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/rstdirective.rst new file mode 100644 index 000000000..c0d503b3d --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/rstdirective.rst @@ -0,0 +1,22 @@ +.. -*- mode: rst -*- + +================================ +Using Pygments in ReST documents +================================ + +Many Python people use `ReST`_ for documentation their sourcecode, programs, +scripts et cetera. This also means that documentation often includes sourcecode +samples or snippets. + +You can easily enable Pygments support for your ReST texts using a custom +directive -- this is also how this documentation displays source code. + +From Pygments 0.9, the directive is shipped in the distribution as +`external/rst-directive.py`. You can copy and adapt this code to your liking. + +.. removed -- too confusing + *Loosely related note:* The ReST lexer now recognizes ``.. sourcecode::`` and + ``.. code::`` directives and highlights the contents in the specified language + if the `handlecodeblocks` option is true. + +.. _ReST: http://docutils.sf.net/rst.html diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/styles.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/styles.rst new file mode 100644 index 000000000..7ef4de1b4 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/styles.rst @@ -0,0 +1,143 @@ +.. -*- mode: rst -*- + +====== +Styles +====== + +Pygments comes with some builtin styles that work for both the HTML and +LaTeX formatter. + +The builtin styles can be looked up with the `get_style_by_name` function: + +.. sourcecode:: pycon + + >>> from pygments.styles import get_style_by_name + >>> get_style_by_name('colorful') + + +You can pass a instance of a `Style` class to a formatter as the `style` +option in form of a string: + +.. sourcecode:: pycon + + >>> from pygments.styles import get_style_by_name + >>> HtmlFormatter(style='colorful').style + + +Or you can also import your own style (which must be a subclass of +`pygments.style.Style`) and pass it to the formatter: + +.. sourcecode:: pycon + + >>> from yourapp.yourmodule import YourStyle + >>> HtmlFormatter(style=YourStyle).style + + + +Creating Own Styles +=================== + +So, how to create a style? All you have to do is to subclass `Style` and +define some styles: + +.. sourcecode:: python + + from pygments.style import Style + from pygments.token import Keyword, Name, Comment, String, Error, \ + Number, Operator, Generic + + class YourStyle(Style): + default_style = "" + styles = { + Comment: 'italic #888', + Keyword: 'bold #005', + Name: '#f00', + Name.Function: '#0f0', + Name.Class: 'bold #0f0', + String: 'bg:#eee #111' + } + +That's it. There are just a few rules. When you define a style for `Name` +the style automatically also affects `Name.Function` and so on. If you +defined ``'bold'`` and you don't want boldface for a subtoken use ``'nobold'``. + +(Philosophy: the styles aren't written in CSS syntax since this way +they can be used for a variety of formatters.) + +`default_style` is the style inherited by all token types. + +To make the style usable for Pygments, you must + +* either register it as a plugin (see :doc:`the plugin docs `) +* or drop it into the `styles` subpackage of your Pygments distribution one style + class per style, where the file name is the style name and the class name is + `StylenameClass`. For example, if your style should be called + ``"mondrian"``, name the class `MondrianStyle`, put it into the file + ``mondrian.py`` and this file into the ``pygments.styles`` subpackage + directory. + + +Style Rules +=========== + +Here a small overview of all allowed styles: + +``bold`` + render text as bold +``nobold`` + don't render text as bold (to prevent subtokens being highlighted bold) +``italic`` + render text italic +``noitalic`` + don't render text as italic +``underline`` + render text underlined +``nounderline`` + don't render text underlined +``bg:`` + transparent background +``bg:#000000`` + background color (black) +``border:`` + no border +``border:#ffffff`` + border color (white) +``#ff0000`` + text color (red) +``noinherit`` + don't inherit styles from supertoken + +Note that there may not be a space between ``bg:`` and the color value +since the style definition string is split at whitespace. +Also, using named colors is not allowed since the supported color names +vary for different formatters. + +Furthermore, not all lexers might support every style. + + +Builtin Styles +============== + +Pygments ships some builtin styles which are maintained by the Pygments team. + +To get a list of known styles you can use this snippet: + +.. sourcecode:: pycon + + >>> from pygments.styles import STYLE_MAP + >>> STYLE_MAP.keys() + ['default', 'emacs', 'friendly', 'colorful'] + + +Getting a list of available styles +================================== + +.. versionadded:: 0.6 + +Because it could be that a plugin registered a style, there is +a way to iterate over all styles: + +.. sourcecode:: pycon + + >>> from pygments.styles import get_all_styles + >>> styles = list(get_all_styles()) diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/tokens.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/tokens.rst new file mode 100644 index 000000000..9193d5f40 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/docs/tokens.rst @@ -0,0 +1,352 @@ +.. -*- mode: rst -*- + +============== +Builtin Tokens +============== + +.. module:: pygments.token + +In the :mod:`pygments.token` module, there is a special object called `Token` +that is used to create token types. + +You can create a new token type by accessing an attribute of `Token`: + +.. sourcecode:: pycon + + >>> from pygments.token import Token + >>> Token.String + Token.String + >>> Token.String is Token.String + True + +Note that tokens are singletons so you can use the ``is`` operator for comparing +token types. + +As of Pygments 0.7 you can also use the ``in`` operator to perform set tests: + +.. sourcecode:: pycon + + >>> from pygments.token import Comment + >>> Comment.Single in Comment + True + >>> Comment in Comment.Multi + False + +This can be useful in :doc:`filters ` and if you write lexers on your +own without using the base lexers. + +You can also split a token type into a hierarchy, and get the parent of it: + +.. sourcecode:: pycon + + >>> String.split() + [Token, Token.Literal, Token.Literal.String] + >>> String.parent + Token.Literal + +In principle, you can create an unlimited number of token types but nobody can +guarantee that a style would define style rules for a token type. Because of +that, Pygments proposes some global token types defined in the +`pygments.token.STANDARD_TYPES` dict. + +For some tokens aliases are already defined: + +.. sourcecode:: pycon + + >>> from pygments.token import String + >>> String + Token.Literal.String + +Inside the :mod:`pygments.token` module the following aliases are defined: + +============= ============================ ==================================== +`Text` `Token.Text` for any type of text data +`Whitespace` `Token.Text.Whitespace` for specially highlighted whitespace +`Error` `Token.Error` represents lexer errors +`Other` `Token.Other` special token for data not + matched by a parser (e.g. HTML + markup in PHP code) +`Keyword` `Token.Keyword` any kind of keywords +`Name` `Token.Name` variable/function names +`Literal` `Token.Literal` Any literals +`String` `Token.Literal.String` string literals +`Number` `Token.Literal.Number` number literals +`Operator` `Token.Operator` operators (``+``, ``not``...) +`Punctuation` `Token.Punctuation` punctuation (``[``, ``(``...) +`Comment` `Token.Comment` any kind of comments +`Generic` `Token.Generic` generic tokens (have a look at + the explanation below) +============= ============================ ==================================== + +The `Whitespace` token type is new in Pygments 0.8. It is used only by the +`VisibleWhitespaceFilter` currently. + +Normally you just create token types using the already defined aliases. For each +of those token aliases, a number of subtypes exists (excluding the special tokens +`Token.Text`, `Token.Error` and `Token.Other`) + +The `is_token_subtype()` function in the `pygments.token` module can be used to +test if a token type is a subtype of another (such as `Name.Tag` and `Name`). +(This is the same as ``Name.Tag in Name``. The overloaded `in` operator was newly +introduced in Pygments 0.7, the function still exists for backwards +compatiblity.) + +With Pygments 0.7, it's also possible to convert strings to token types (for example +if you want to supply a token from the command line): + +.. sourcecode:: pycon + + >>> from pygments.token import String, string_to_tokentype + >>> string_to_tokentype("String") + Token.Literal.String + >>> string_to_tokentype("Token.Literal.String") + Token.Literal.String + >>> string_to_tokentype(String) + Token.Literal.String + + +Keyword Tokens +============== + +`Keyword` + For any kind of keyword (especially if it doesn't match any of the + subtypes of course). + +`Keyword.Constant` + For keywords that are constants (e.g. ``None`` in future Python versions). + +`Keyword.Declaration` + For keywords used for variable declaration (e.g. ``var`` in some programming + languages like JavaScript). + +`Keyword.Namespace` + For keywords used for namespace declarations (e.g. ``import`` in Python and + Java and ``package`` in Java). + +`Keyword.Pseudo` + For keywords that aren't really keywords (e.g. ``None`` in old Python + versions). + +`Keyword.Reserved` + For reserved keywords. + +`Keyword.Type` + For builtin types that can't be used as identifiers (e.g. ``int``, + ``char`` etc. in C). + + +Name Tokens +=========== + +`Name` + For any name (variable names, function names, classes). + +`Name.Attribute` + For all attributes (e.g. in HTML tags). + +`Name.Builtin` + Builtin names; names that are available in the global namespace. + +`Name.Builtin.Pseudo` + Builtin names that are implicit (e.g. ``self`` in Ruby, ``this`` in Java). + +`Name.Class` + Class names. Because no lexer can know if a name is a class or a function + or something else this token is meant for class declarations. + +`Name.Constant` + Token type for constants. In some languages you can recognise a token by the + way it's defined (the value after a ``const`` keyword for example). In + other languages constants are uppercase by definition (Ruby). + +`Name.Decorator` + Token type for decorators. Decorators are synatic elements in the Python + language. Similar syntax elements exist in C# and Java. + +`Name.Entity` + Token type for special entities. (e.g. `` `` in HTML). + +`Name.Exception` + Token type for exception names (e.g. ``RuntimeError`` in Python). Some languages + define exceptions in the function signature (Java). You can highlight + the name of that exception using this token then. + +`Name.Function` + Token type for function names. + +`Name.Label` + Token type for label names (e.g. in languages that support ``goto``). + +`Name.Namespace` + Token type for namespaces. (e.g. import paths in Java/Python), names following + the ``module``/``namespace`` keyword in other languages. + +`Name.Other` + Other names. Normally unused. + +`Name.Tag` + Tag names (in HTML/XML markup or configuration files). + +`Name.Variable` + Token type for variables. Some languages have prefixes for variable names + (PHP, Ruby, Perl). You can highlight them using this token. + +`Name.Variable.Class` + same as `Name.Variable` but for class variables (also static variables). + +`Name.Variable.Global` + same as `Name.Variable` but for global variables (used in Ruby, for + example). + +`Name.Variable.Instance` + same as `Name.Variable` but for instance variables. + + +Literals +======== + +`Literal` + For any literal (if not further defined). + +`Literal.Date` + for date literals (e.g. ``42d`` in Boo). + + +`String` + For any string literal. + +`String.Backtick` + Token type for strings enclosed in backticks. + +`String.Char` + Token type for single characters (e.g. Java, C). + +`String.Doc` + Token type for documentation strings (for example Python). + +`String.Double` + Double quoted strings. + +`String.Escape` + Token type for escape sequences in strings. + +`String.Heredoc` + Token type for "heredoc" strings (e.g. in Ruby or Perl). + +`String.Interpol` + Token type for interpolated parts in strings (e.g. ``#{foo}`` in Ruby). + +`String.Other` + Token type for any other strings (for example ``%q{foo}`` string constructs + in Ruby). + +`String.Regex` + Token type for regular expression literals (e.g. ``/foo/`` in JavaScript). + +`String.Single` + Token type for single quoted strings. + +`String.Symbol` + Token type for symbols (e.g. ``:foo`` in LISP or Ruby). + + +`Number` + Token type for any number literal. + +`Number.Bin` + Token type for binary literals (e.g. ``0b101010``). + +`Number.Float` + Token type for float literals (e.g. ``42.0``). + +`Number.Hex` + Token type for hexadecimal number literals (e.g. ``0xdeadbeef``). + +`Number.Integer` + Token type for integer literals (e.g. ``42``). + +`Number.Integer.Long` + Token type for long integer literals (e.g. ``42L`` in Python). + +`Number.Oct` + Token type for octal literals. + + +Operators +========= + +`Operator` + For any punctuation operator (e.g. ``+``, ``-``). + +`Operator.Word` + For any operator that is a word (e.g. ``not``). + + +Punctuation +=========== + +.. versionadded:: 0.7 + +`Punctuation` + For any punctuation which is not an operator (e.g. ``[``, ``(``...) + + +Comments +======== + +`Comment` + Token type for any comment. + +`Comment.Multiline` + Token type for multiline comments. + +`Comment.Preproc` + Token type for preprocessor comments (also ```. + +.. versionadded:: 0.7 + The formatters now also accept an `outencoding` option which will override + the `encoding` option if given. This makes it possible to use a single + options dict with lexers and formatters, and still have different input and + output encodings. + +.. _chardet: http://chardet.feedparser.org/ diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/download.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/download.rst new file mode 100644 index 000000000..cf32f481a --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/download.rst @@ -0,0 +1,41 @@ +Download and installation +========================= + +The current release is version |version|. + +Packaged versions +----------------- + +You can download it `from the Python Package Index +`_. For installation of packages from +PyPI, we recommend `Pip `_, which works on all +major platforms. + +Under Linux, most distributions include a package for Pygments, usually called +``pygments`` or ``python-pygments``. You can install it with the package +manager as usual. + +Development sources +------------------- + +We're using the `Mercurial `_ version control +system. You can get the development source using this command:: + + hg clone http://bitbucket.org/birkenfeld/pygments-main pygments + +Development takes place at `Bitbucket +`_, you can browse the source +online `here `_. + +The latest changes in the development source code are listed in the `changelog +`_. + +.. Documentation + ------------- + +.. XXX todo + + You can download the documentation either as + a bunch of rst files from the Mercurial repository, see above, or + as a tar.gz containing rendered HTML files:

    +

    pygmentsdocs.tar.gz

    diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/faq.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/faq.rst new file mode 100644 index 000000000..0f65b9fe8 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/faq.rst @@ -0,0 +1,143 @@ +:orphan: + +Pygments FAQ +============= + +What is Pygments? +----------------- + +Pygments is a syntax highlighting engine written in Python. That means, it will +take source code (or other markup) in a supported language and output a +processed version (in different formats) containing syntax highlighting markup. + +Its features include: + +* a wide range of common languages and markup formats is supported (look here + for a list) +* new languages and formats are added easily +* a number of output formats is available, including: + + - HTML + - ANSI sequences (console output) + - LaTeX + - RTF + +* it is usable as a command-line tool and as a library +* parsing and formatting is fast + +Pygments is licensed under the BSD license. + +Where does the name Pygments come from? +--------------------------------------- + +*Py* of course stands for Python, while *pigments* are used for coloring paint, +and in this case, source code! + +What are the system requirements? +--------------------------------- + +Pygments only needs a standard Python install, version 2.6 or higher or version +3.3 or higher for Python 3. No additional libraries are needed. + +How can I use Pygments? +----------------------- + +Pygments is usable as a command-line tool as well as a library. + +From the command-line, usage looks like this (assuming the pygmentize script is +properly installed):: + + pygmentize -f html /path/to/file.py + +This will print a HTML-highlighted version of /path/to/file.py to standard output. + +For a complete help, please run ``pygmentize -h``. + +Usage as a library is thoroughly demonstrated in the Documentation section. + +How do I make a new style? +-------------------------- + +Please see the documentation on styles. + +How can I report a bug or suggest a feature? +-------------------------------------------- + +Please report bugs and feature wishes in the tracker at Bitbucket. + +You can also e-mail the author or use IRC, see the contact details. + +I want this support for this language! +-------------------------------------- + +Instead of waiting for others to include language support, why not write it +yourself? All you have to know is :doc:`outlined in the docs +`. + +Can I use Pygments for programming language processing? +------------------------------------------------------- + +The Pygments lexing machinery is quite powerful can be used to build lexers for +basically all languages. However, parsing them is not possible, though some +lexers go some steps in this direction in order to e.g. highlight function names +differently. + +Also, error reporting is not the scope of Pygments. It focuses on correctly +highlighting syntactically valid documents, not finding and compensating errors. + +Who uses Pygments? +------------------ + +This is an (incomplete) list of projects and sites known to use the Pygments highlighter. + +* `Pygments API `_, a HTTP POST interface to Pygments +* `The Sphinx documentation builder `_, for embedded source examples +* `rst2pdf `_, a reStructuredText to PDF converter +* `Zine `_, a Python blogging system +* `Trac `_, the universal project management tool +* `Bruce `_, a reStructuredText presentation tool +* `AsciiDoc `_, a text-based documentation generator +* `ActiveState Code `_, the Python Cookbook successor +* `ViewVC `_, a web-based version control repository browser +* `BzrFruit `_, a Bazaar branch viewer +* `QBzr `_, a cross-platform Qt-based GUI front end for Bazaar +* `BitBucket `_, a Mercurial and Git hosting site +* `GitHub `_, a site offering secure Git hosting and collaborative development +* `Review Board `_, a collaborative code reviewing tool +* `skeletonz `_, a Python powered content management system +* `Diamanda `_, a Django powered wiki system with support for Pygments +* `Progopedia `_ (`English `_), + an encyclopedia of programming languages +* `Postmarkup `_, a BBCode to XHTML generator +* `Language Comparison `_, a site that compares different programming languages +* `BPython `_, a curses-based intelligent Python shell +* `Challenge-You! `_, a site offering programming challenges +* `PIDA `_, a universal IDE written in Python +* `PuDB `_, a console Python debugger +* `XWiki `_, a wiki-based development framework in Java, using Jython +* `roux `_, a script for running R scripts + and creating beautiful output including graphs +* `hurl `_, a web service for making HTTP requests +* `wxHTMLPygmentizer `_ is + a GUI utility, used to make code-colorization easier +* `WpPygments `_, a highlighter plugin for WordPress +* `LodgeIt `_, a pastebin with XMLRPC support and diffs +* `SpammCan `_, a pastebin (demo see + `here `_) +* `WowAce.com pastes `_, a pastebin +* `Siafoo `_, a tool for sharing and storing useful code and programming experience +* `D source `_, a community for the D programming language +* `dumpz.org `_, a pastebin +* `dpaste.com `_, another Django pastebin +* `PylonsHQ Pasties `_, a pastebin +* `Django snippets `_, a pastebin for Django code +* `Fayaa `_, a Chinese pastebin +* `Incollo.com `_, a free collaborative debugging tool +* `PasteBox `_, a pastebin focused on privacy +* `xinotes.org `_, a site to share notes, code snippets etc. +* `hilite.me `_, a site to highlight code snippets +* `patx.me `_, a pastebin + +If you have a project or web site using Pygments, drop me a line, and I'll add a +link here. + diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/index.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/index.rst new file mode 100644 index 000000000..a0e412106 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/index.rst @@ -0,0 +1,53 @@ +Welcome! +======== + +This is the home of Pygments. It is a generic syntax highlighter for general use +in all kinds of software such as forum systems, wikis or other applications that +need to prettify source code. Highlights are: + +* a wide range of common languages and markup formats is supported +* special attention is paid to details that increase highlighting quality +* support for new languages and formats are added easily; most languages use a simple regex-based lexing mechanism +* a number of output formats is available, among them HTML, RTF, LaTeX and ANSI sequences +* it is usable as a command-line tool and as a library +* ... and it highlights even Brainf*ck! + +Read more in the FAQ list or the documentation, or download the latest release. + +Though Pygments has not yet won an award, we trust that you will notice it's a top quality product . + +.. _contribute: + +Contribute +---------- + +Like every open-source project, we are always looking for volunteers to help us +with programming. Python knowledge is required, but don't fear: Python is a very +clear and easy to learn language. + +Development takes place on `Bitbucket +`_, where the Mercurial +repository, tickets and pull requests can be viewed. + +Our primary communication instrument is the IRC channel **#pocoo** on the +Freenode network. To join it, let your IRC client connect to +``irc.freenode.net`` and do ``/join #pocoo``. + +If you found a bug, just open a ticket in the Bitbucket tracker. Be sure to log +in to be notified when the issue is fixed -- development is not fast-paced as +the library is quite stable. You can also send an e-mail to the developers, see +below. + +The authors +----------- + +Pygments is maintained by **Georg Brandl**, e-mail address *georg*\ *@*\ *python.org*. + +Many lexers and fixes have been contributed by **Armin Ronacher**, the rest of +the `Pocoo `_ team and **Tim Hatch**. + +.. toctree:: + :maxdepth: 1 + :hidden: + + docs/index diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/languages.rst b/node_modules/pygmentize-bundled/vendor/pygments/doc/languages.rst new file mode 100644 index 000000000..0f98c5832 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/languages.rst @@ -0,0 +1,151 @@ +:orphan: + +Supported languages +=================== + +Pygments supports an ever-growing range of languages. Watch this space... + +Programming languages +--------------------- + +* ActionScript +* Ada +* ANTLR +* AppleScript +* Assembly (various) +* Asymptote +* Awk +* Befunge +* Boo +* BrainFuck +* C, C++ +* C# +* Clojure +* CoffeeScript +* ColdFusion +* Common Lisp +* Coq +* Cryptol (incl. Literate Cryptol) +* `Cython `_ +* `D `_ +* Dart +* Delphi +* Dylan +* Erlang +* Factor +* Fancy +* Fortran +* F# +* GAP +* Gherkin (Cucumber) +* GL shaders +* Groovy +* `Haskell `_ (incl. Literate Haskell) +* IDL +* Io +* Java +* JavaScript +* LLVM +* Logtalk +* `Lua `_ +* Matlab +* MiniD +* Modelica +* Modula-2 +* MuPad +* Nemerle +* Nimrod +* Objective-C +* Objective-J +* Octave +* OCaml +* PHP +* `Perl `_ +* PovRay +* PostScript +* PowerShell +* Prolog +* `Python `_ 2.x and 3.x (incl. console sessions and tracebacks) +* `REBOL `_ +* `Red `_ +* Redcode +* `Ruby `_ (incl. irb sessions) +* Rust +* S, S-Plus, R +* Scala +* Scheme +* Scilab +* Smalltalk +* SNOBOL +* Tcl +* Vala +* Verilog +* VHDL +* Visual Basic.NET +* Visual FoxPro +* XQuery +* Zephir +
+ +Template languages +------------------ + +* Cheetah templates +* `Django `_ / `Jinja + `_ templates +* ERB (Ruby templating) +* `Genshi `_ (the Trac template language) +* JSP (Java Server Pages) +* `Myghty `_ (the HTML::Mason based framework) +* `Mako `_ (the Myghty successor) +* `Smarty `_ templates (PHP templating) +* Tea + +Other markup +------------ + +* Apache config files +* Bash shell scripts +* BBCode +* CMake +* CSS +* Debian control files +* Diff files +* DTD +* Gettext catalogs +* Gnuplot script +* Groff markup +* HTML +* HTTP sessions +* INI-style config files +* IRC logs (irssi style) +* Lighttpd config files +* Makefiles +* MoinMoin/Trac Wiki markup +* MySQL +* Nginx config files +* POV-Ray scenes +* Ragel +* Redcode +* ReST +* Robot Framework +* RPM spec files +* SQL, also MySQL, SQLite +* Squid configuration +* TeX +* tcsh +* Vim Script +* Windows batch files +* XML +* XSLT +* YAML + +... that's all? +--------------- + +Well, why not write your own? Contributing to Pygments is easy and fun. Look +:doc:`here ` for the docs on lexer development and +:ref:`here ` for contact details. + +Note: the languages listed here are supported in the development version. The +latest release may lack a few of them. diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/make.bat b/node_modules/pygmentize-bundled/vendor/pygments/doc/make.bat new file mode 100644 index 000000000..8803c9859 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/make.bat @@ -0,0 +1,190 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Pygments.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Pygments.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/node_modules/pygmentize-bundled/vendor/pygments/doc/pygmentize.1 b/node_modules/pygmentize-bundled/vendor/pygments/doc/pygmentize.1 new file mode 100644 index 000000000..71bb6f9ce --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/doc/pygmentize.1 @@ -0,0 +1,94 @@ +.TH PYGMENTIZE 1 "February 15, 2007" + +.SH NAME +pygmentize \- highlights the input file + +.SH SYNOPSIS +.B \fBpygmentize\fP +.RI [-l\ \fI\fP]\ [-F\ \fI\fP[:\fI\fP]]\ [-f\ \fI\fP] +.RI [-O\ \fI\fP]\ [-P\ \fI\fP]\ [-o\ \fI\fP]\ [\fI\fP] +.br +.B \fBpygmentize\fP +.RI -S\ \fI + + +

%(title)s

+ +''' + +DOC_HEADER_EXTERNALCSS = '''\ + + + + + %(title)s + + + + +

%(title)s

+ +''' + +DOC_FOOTER = '''\ + + +''' + + +class HtmlFormatter(Formatter): + r""" + Format tokens as HTML 4 ```` tags within a ``
`` tag, wrapped
+    in a ``
`` tag. The ``
``'s CSS class can be set by the `cssclass` + option. + + If the `linenos` option is set to ``"table"``, the ``
`` is
+    additionally wrapped inside a ```` which has one row and two
+    cells: one containing the line numbers and one containing the code.
+    Example:
+
+    .. sourcecode:: html
+
+        
+
+ + +
+
1
+            2
+
+
def foo(bar):
+              pass
+            
+
+ + (whitespace added to improve clarity). + + Wrapping can be disabled using the `nowrap` option. + + A list of lines can be specified using the `hl_lines` option to make these + lines highlighted (as of Pygments 0.11). + + With the `full` option, a complete HTML 4 document is output, including + the style definitions inside a `` + + +

Code tags report for %s

+ + +%s +
LineTagWhoDescription
+ + +''' + + TABLE = '\nFile: %s\n' + + TR = ('%%(lno)d' + '%%(tag)s' + '%%(who)s%%(what)s') + + f = open(output, 'w') + table = '\n'.join(TABLE % fname + + '\n'.join(TR % (no % 2,) % entry + for no, entry in enumerate(store[fname])) + for fname in sorted(store)) + f.write(HTML % (', '.join(map(abspath, args)), table)) + f.close() + + print("Report written to %s." % output) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/node_modules/pygmentize-bundled/vendor/pygments/scripts/find_error.py b/node_modules/pygmentize-bundled/vendor/pygments/scripts/find_error.py new file mode 100755 index 000000000..7aaa9bee2 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/scripts/find_error.py @@ -0,0 +1,173 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" + Lexing error finder + ~~~~~~~~~~~~~~~~~~~ + + For the source files given on the command line, display + the text where Error tokens are being generated, along + with some context. + + :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from __future__ import print_function + +import os +import sys + +# always prefer Pygments from source if exists +srcpath = os.path.join(os.path.dirname(__file__), '..') +if os.path.isdir(os.path.join(srcpath, 'pygments')): + sys.path.insert(0, srcpath) + + +from pygments.lexer import RegexLexer +from pygments.lexers import get_lexer_for_filename, get_lexer_by_name +from pygments.token import Error, Text, _TokenType +from pygments.cmdline import _parse_options + + +class DebuggingRegexLexer(RegexLexer): + """Make the state stack, position and current match instance attributes.""" + + def get_tokens_unprocessed(self, text, stack=('root',)): + """ + Split ``text`` into (tokentype, text) pairs. + + ``stack`` is the inital stack (default: ``['root']``) + """ + self.pos = 0 + tokendefs = self._tokens + self.statestack = list(stack) + statetokens = tokendefs[self.statestack[-1]] + while 1: + for rexmatch, action, new_state in statetokens: + self.m = m = rexmatch(text, self.pos) + if m: + if type(action) is _TokenType: + yield self.pos, action, m.group() + else: + for item in action(self, m): + yield item + self.pos = m.end() + if new_state is not None: + # state transition + if isinstance(new_state, tuple): + for state in new_state: + if state == '#pop': + self.statestack.pop() + elif state == '#push': + self.statestack.append(self.statestack[-1]) + else: + self.statestack.append(state) + elif isinstance(new_state, int): + # pop + del self.statestack[new_state:] + elif new_state == '#push': + self.statestack.append(self.statestack[-1]) + else: + assert False, 'wrong state def: %r' % new_state + statetokens = tokendefs[self.statestack[-1]] + break + else: + try: + if text[self.pos] == '\n': + # at EOL, reset state to 'root' + self.pos += 1 + self.statestack = ['root'] + statetokens = tokendefs['root'] + yield self.pos, Text, u'\n' + continue + yield self.pos, Error, text[self.pos] + self.pos += 1 + except IndexError: + break + + +def main(fn, lexer=None, options={}): + if lexer is not None: + lx = get_lexer_by_name(lexer) + else: + try: + lx = get_lexer_for_filename(os.path.basename(fn), **options) + except ValueError: + try: + name, rest = fn.split('_', 1) + lx = get_lexer_by_name(name, **options) + except ValueError: + raise AssertionError('no lexer found for file %r' % fn) + debug_lexer = False + # does not work for e.g. ExtendedRegexLexers + if lx.__class__.__bases__ == (RegexLexer,): + lx.__class__.__bases__ = (DebuggingRegexLexer,) + debug_lexer = True + elif lx.__class__.__bases__ == (DebuggingRegexLexer,): + # already debugged before + debug_lexer = True + lno = 1 + text = open(fn, 'U').read() + text = text.strip('\n') + '\n' + tokens = [] + states = [] + + def show_token(tok, state): + reprs = map(repr, tok) + print(' ' + reprs[1] + ' ' + ' ' * (29-len(reprs[1])) + reprs[0], end=' ') + if debug_lexer: + print(' ' + ' ' * (29-len(reprs[0])) + repr(state), end=' ') + print() + + for type, val in lx.get_tokens(text): + lno += val.count('\n') + if type == Error: + print('Error parsing', fn, 'on line', lno) + print('Previous tokens' + (debug_lexer and ' and states' or '') + ':') + if showall: + for tok, state in map(None, tokens, states): + show_token(tok, state) + else: + for i in range(max(len(tokens) - num, 0), len(tokens)): + show_token(tokens[i], states[i]) + print('Error token:') + l = len(repr(val)) + print(' ' + repr(val), end=' ') + if debug_lexer and hasattr(lx, 'statestack'): + print(' ' * (60-l) + repr(lx.statestack), end=' ') + print() + print() + return 1 + tokens.append((type, val)) + if debug_lexer: + if hasattr(lx, 'statestack'): + states.append(lx.statestack[:]) + else: + states.append(None) + if showall: + for tok, state in map(None, tokens, states): + show_token(tok, state) + return 0 + + +num = 10 +showall = False +lexer = None +options = {} + +if __name__ == '__main__': + import getopt + opts, args = getopt.getopt(sys.argv[1:], 'n:l:aO:') + for opt, val in opts: + if opt == '-n': + num = int(val) + elif opt == '-a': + showall = True + elif opt == '-l': + lexer = val + elif opt == '-O': + options = _parse_options([val]) + ret = 0 + for f in args: + ret += main(f, lexer, options) + sys.exit(bool(ret)) diff --git a/node_modules/pygmentize-bundled/vendor/pygments/scripts/get_vimkw.py b/node_modules/pygmentize-bundled/vendor/pygments/scripts/get_vimkw.py new file mode 100644 index 000000000..4ea302f4b --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/scripts/get_vimkw.py @@ -0,0 +1,43 @@ +from __future__ import print_function +import re + +r_line = re.compile(r"^(syn keyword vimCommand contained|syn keyword vimOption " + r"contained|syn keyword vimAutoEvent contained)\s+(.*)") +r_item = re.compile(r"(\w+)(?:\[(\w+)\])?") + +def getkw(input, output): + out = file(output, 'w') + + output_info = {'command': [], 'option': [], 'auto': []} + for line in file(input): + m = r_line.match(line) + if m: + # Decide which output gets mapped to d + if 'vimCommand' in m.group(1): + d = output_info['command'] + elif 'AutoEvent' in m.group(1): + d = output_info['auto'] + else: + d = output_info['option'] + + # Extract all the shortened versions + for i in r_item.finditer(m.group(2)): + d.append('(%r,%r)' % + (i.group(1), "%s%s" % (i.group(1), i.group(2) or ''))) + + output_info['option'].append("('nnoremap','nnoremap')") + output_info['option'].append("('inoremap','inoremap')") + output_info['option'].append("('vnoremap','vnoremap')") + + for a, b in output_info.items(): + b.sort() + print('%s=[%s]' % (a, ','.join(b)), file=out) + +def is_keyword(w, keywords): + for i in range(len(w), 0, -1): + if w[:i] in keywords: + return keywords[w[:i]][:len(w)] == w + return False + +if __name__ == "__main__": + getkw("/usr/share/vim/vim73/syntax/vim.vim", "temp.py") diff --git a/node_modules/pygmentize-bundled/vendor/pygments/scripts/pylintrc b/node_modules/pygmentize-bundled/vendor/pygments/scripts/pylintrc new file mode 100644 index 000000000..aa04e12e5 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/scripts/pylintrc @@ -0,0 +1,301 @@ +# lint Python modules using external checkers. +# +# This is the main checker controling the other ones and the reports +# generation. It is itself both a raw checker and an astng checker in order +# to: +# * handle message activation / deactivation at the module level +# * handle some basic but necessary stats'data (number of classes, methods...) +# +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Profiled execution. +profile=no + +# Add to the black list. It should be a base name, not a +# path. You may set this option multiple times. +ignore=.svn + +# Pickle collected data for later comparisons. +persistent=yes + +# Set the cache size for astng objects. +cache-size=500 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + + +[MESSAGES CONTROL] + +# Enable only checker(s) with the given id(s). This option conflict with the +# disable-checker option +#enable-checker= + +# Enable all checker(s) except those with the given id(s). This option conflict +# with the disable-checker option +#disable-checker= + +# Enable all messages in the listed categories. +#enable-msg-cat= + +# Disable all messages in the listed categories. +#disable-msg-cat= + +# Enable the message(s) with the given id(s). +#enable-msg= + +# Disable the message(s) with the given id(s). +disable-msg=C0323,W0142,C0301,C0103,C0111,E0213,C0302,C0203,W0703,R0201 + + +[REPORTS] + +# set the output format. Available formats are text, parseable, colorized and +# html +output-format=colorized + +# Include message's id in output +include-ids=yes + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells wether to display a full report or only the messages +reports=yes + +# Python expression which should return a note less than 10 (10 is the highest +# note).You have access to the variables errors warning, statement which +# respectivly contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (R0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (R0004). +comment=no + +# Enable the report(s) with the given id(s). +#enable-report= + +# Disable the report(s) with the given id(s). +#disable-report= + + +# checks for +# * unused variables / imports +# * undefined variables +# * redefinition of variable from builtins or from an outer scope +# * use of variable before assigment +# +[VARIABLES] + +# Tells wether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching names used for dummy variables (i.e. not used). +dummy-variables-rgx=_|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +# try to find bugs in the code using type inference +# +[TYPECHECK] + +# Tells wether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# When zope mode is activated, consider the acquired-members option to ignore +# access to some undefined attributes. +zope=no + +# List of members which are usually get through zope's acquisition mecanism and +# so shouldn't trigger E0201 when accessed (need zope=yes to be considered). +acquired-members=REQUEST,acl_users,aq_parent + + +# checks for : +# * doc strings +# * modules / classes / functions / methods / arguments / variables name +# * number of arguments, local variables, branchs, returns and statements in +# functions, methods +# * required module attributes +# * dangerous default values as arguments +# * redefinition of function / method / class +# * uses of the global statement +# +[BASIC] + +# Required attributes for module, separated by a comma +required-attributes= + +# Regular expression which should only match functions or classes name which do +# not require a docstring +no-docstring-rgx=__.*__ + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# List of builtins function names that should not be used, separated by a comma +bad-functions=apply,input + + +# checks for sign of poor/misdesign: +# * number of methods, attributes, local variables... +# * size, complexity of functions, methods +# +[DESIGN] + +# Maximum number of arguments for function / method +max-args=12 + +# Maximum number of locals for function / method body +max-locals=30 + +# Maximum number of return / yield for function / method body +max-returns=12 + +# Maximum number of branch for function / method body +max-branchs=30 + +# Maximum number of statements in function / method body +max-statements=60 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=20 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=0 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +# checks for +# * external modules dependencies +# * relative / wildcard imports +# * cyclic imports +# * uses of deprecated modules +# +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,string,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report R0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report R0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report R0402 must +# not be disabled) +int-import-graph= + + +# checks for : +# * methods without self as first argument +# * overridden methods signature +# * access only to existant members via self +# * attributes not defined in the __init__ method +# * supported interfaces implementation +# * unreachable code +# +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + + +# checks for similarities and duplicated code. This computation may be +# memory / CPU intensive, so you should disable it if you experiments some +# problems. +# +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=10 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + + +# checks for: +# * warning notes in the code like FIXME, XXX +# * PEP 263: source code with non ascii character but no encoding declaration +# +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO + + +# checks for : +# * unauthorized constructions +# * strict indentation +# * line length +# * use of <> instead of != +# +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=90 + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' diff --git a/node_modules/pygmentize-bundled/vendor/pygments/scripts/vim2pygments.py b/node_modules/pygmentize-bundled/vendor/pygments/scripts/vim2pygments.py new file mode 100755 index 000000000..42af0bbe1 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/scripts/vim2pygments.py @@ -0,0 +1,935 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + Vim Colorscheme Converter + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + This script converts vim colorscheme files to valid pygments + style classes meant for putting into modules. + + :copyright 2006 by Armin Ronacher. + :license: BSD, see LICENSE for details. +""" + +from __future__ import print_function + +import sys +import re +from os import path +from io import StringIO + +split_re = re.compile(r'(? 2 and \ + len(parts[0]) >= 2 and \ + 'highlight'.startswith(parts[0]): + token = parts[1].lower() + if token not in TOKENS: + continue + for item in parts[2:]: + p = item.split('=', 1) + if not len(p) == 2: + continue + key, value = p + if key in ('ctermfg', 'guifg'): + color = get_vim_color(value) + if color: + set('color', color) + elif key in ('ctermbg', 'guibg'): + color = get_vim_color(value) + if color: + set('bgcolor', color) + elif key in ('term', 'cterm', 'gui'): + items = value.split(',') + for item in items: + item = item.lower() + if item == 'none': + set('noinherit', True) + elif item == 'bold': + set('bold', True) + elif item == 'underline': + set('underline', True) + elif item == 'italic': + set('italic', True) + + if bg_color is not None and not colors['Normal'].get('bgcolor'): + colors['Normal']['bgcolor'] = bg_color + + color_map = {} + for token, styles in colors.items(): + if token in TOKENS: + tmp = [] + if styles.get('noinherit'): + tmp.append('noinherit') + if 'color' in styles: + tmp.append(styles['color']) + if 'bgcolor' in styles: + tmp.append('bg:' + styles['bgcolor']) + if styles.get('bold'): + tmp.append('bold') + if styles.get('italic'): + tmp.append('italic') + if styles.get('underline'): + tmp.append('underline') + tokens = TOKENS[token] + if not isinstance(tokens, tuple): + tokens = (tokens,) + for token in tokens: + color_map[token] = ' '.join(tmp) + + default_token = color_map.pop('') + return default_token, color_map + + +class StyleWriter(object): + + def __init__(self, code, name): + self.code = code + self.name = name.lower() + + def write_header(self, out): + out.write('# -*- coding: utf-8 -*-\n"""\n') + out.write(' %s Colorscheme\n' % self.name.title()) + out.write(' %s\n\n' % ('~' * (len(self.name) + 12))) + out.write(' Converted by %s\n' % SCRIPT_NAME) + out.write('"""\nfrom pygments.style import Style\n') + out.write('from pygments.token import Token, %s\n\n' % ', '.join(TOKEN_TYPES)) + out.write('class %sStyle(Style):\n\n' % self.name.title()) + + def write(self, out): + self.write_header(out) + default_token, tokens = find_colors(self.code) + tokens = list(tokens.items()) + tokens.sort(lambda a, b: cmp(len(a[0]), len(a[1]))) + bg_color = [x[3:] for x in default_token.split() if x.startswith('bg:')] + if bg_color: + out.write(' background_color = %r\n' % bg_color[0]) + out.write(' styles = {\n') + out.write(' %-20s%r,\n' % ('Token:', default_token)) + for token, definition in tokens: + if definition: + out.write(' %-20s%r,\n' % (token + ':', definition)) + out.write(' }') + + def __repr__(self): + out = StringIO() + self.write_style(out) + return out.getvalue() + + +def convert(filename, stream=None): + name = path.basename(filename) + if name.endswith('.vim'): + name = name[:-4] + f = file(filename) + code = f.read() + f.close() + writer = StyleWriter(code, name) + if stream is not None: + out = stream + else: + out = StringIO() + writer.write(out) + if stream is None: + return out.getvalue() + + +def main(): + if len(sys.argv) != 2 or sys.argv[1] in ('-h', '--help'): + print('Usage: %s ' % sys.argv[0]) + return 2 + if sys.argv[1] in ('-v', '--version'): + print('%s %s' % (SCRIPT_NAME, SCRIPT_VERSION)) + return + filename = sys.argv[1] + if not (path.exists(filename) and path.isfile(filename)): + print('Error: %s not found' % filename) + return 1 + convert(filename, sys.stdout) + sys.stdout.write('\n') + + +if __name__ == '__main__': + sys.exit(main() or 0) diff --git a/node_modules/pygmentize-bundled/vendor/pygments/setup.cfg b/node_modules/pygmentize-bundled/vendor/pygments/setup.cfg new file mode 100644 index 000000000..abca6bcc5 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/setup.cfg @@ -0,0 +1,7 @@ +[egg_info] +tag_build = dev +tag_date = true + +[aliases] +release = egg_info -RDb '' +upload = upload --sign --identity=36580288 diff --git a/node_modules/pygmentize-bundled/vendor/pygments/setup.py b/node_modules/pygmentize-bundled/vendor/pygments/setup.py new file mode 100755 index 000000000..a0b2e90b9 --- /dev/null +++ b/node_modules/pygmentize-bundled/vendor/pygments/setup.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + Pygments + ~~~~~~~~ + + Pygments is a syntax highlighting package written in Python. + + It is a generic syntax highlighter for general use in all kinds of software + such as forum systems, wikis or other applications that need to prettify + source code. Highlights are: + + * a wide range of common languages and markup formats is supported + * special attention is paid to details, increasing quality by a fair amount + * support for new languages and formats are added easily + * a number of output formats, presently HTML, LaTeX, RTF, SVG, all image \ + formats that PIL supports and ANSI sequences + * it is usable as a command-line tool and as a library + * ... and it highlights even Brainfuck! + + The `Pygments tip`_ is installable with ``easy_install Pygments==dev``. + + .. _Pygments tip: + http://bitbucket.org/birkenfeld/pygments-main/get/default.zip#egg=Pygments-dev + + :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +try: + from setuptools import setup, find_packages + have_setuptools = True +except ImportError: + try: + import ez_setup + ez_setup.use_setuptools() + from setuptools import setup, find_packages + have_setuptools = True + except ImportError: + from distutils.core import setup + def find_packages(*args, **kwargs): + return [ + 'pygments', + 'pygments.lexers', + 'pygments.formatters', + 'pygments.styles', + 'pygments.filters', + ] + have_setuptools = False + +if have_setuptools: + add_keywords = dict( + entry_points = { + 'console_scripts': ['pygmentize = pygments.cmdline:main'], + }, + ) +else: + add_keywords = dict( + scripts = ['pygmentize'], + ) + +setup( + name = 'Pygments', + version = '2.0pre', + url = 'http://pygments.org/', + license = 'BSD License', + author = 'Georg Brandl', + author_email = 'georg@python.org', + description = 'Pygments is a syntax highlighting package written in Python.', + long_description = __doc__, + keywords = 'syntax highlighting', + packages = find_packages(exclude=['ez_setup']), + platforms = 'any', + zip_safe = False, + include_package_data = True, + classifiers = [ + 'License :: OSI Approved :: BSD License', + 'Intended Audience :: Developers', + 'Intended Audience :: End Users/Desktop', + 'Intended Audience :: System Administrators', + 'Development Status :: 6 - Mature', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'Operating System :: OS Independent', + 'Topic :: Text Processing :: Filters', + 'Topic :: Utilities', + ], + **add_keywords +) diff --git a/node_modules/readable-stream/.npmignore b/node_modules/readable-stream/.npmignore new file mode 100644 index 000000000..38344f87a --- /dev/null +++ b/node_modules/readable-stream/.npmignore @@ -0,0 +1,5 @@ +build/ +test/ +examples/ +fs.js +zlib.js \ No newline at end of file diff --git a/node_modules/readable-stream/LICENSE b/node_modules/readable-stream/LICENSE new file mode 100644 index 000000000..e3d4e695a --- /dev/null +++ b/node_modules/readable-stream/LICENSE @@ -0,0 +1,18 @@ +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +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/node_modules/readable-stream/README.md b/node_modules/readable-stream/README.md new file mode 100644 index 000000000..3fb3e8023 --- /dev/null +++ b/node_modules/readable-stream/README.md @@ -0,0 +1,15 @@ +# readable-stream + +***Node-core streams for userland*** + +[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/) +[![NPM](https://nodei.co/npm-dl/readable-stream.png?&months=6&height=3)](https://nodei.co/npm/readable-stream/) + +This package is a mirror of the Streams2 and Streams3 implementations in Node-core. + +If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core. + +**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12. + +**readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `"~1.1.0"` + diff --git a/node_modules/readable-stream/duplex.js b/node_modules/readable-stream/duplex.js new file mode 100644 index 000000000..ca807af87 --- /dev/null +++ b/node_modules/readable-stream/duplex.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_duplex.js") diff --git a/node_modules/readable-stream/lib/_stream_duplex.js b/node_modules/readable-stream/lib/_stream_duplex.js new file mode 100644 index 000000000..b513d61a9 --- /dev/null +++ b/node_modules/readable-stream/lib/_stream_duplex.js @@ -0,0 +1,89 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +module.exports = Duplex; + +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} +/**/ + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +forEach(objectKeys(Writable.prototype), function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); + +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) + this.readable = false; + + if (options && options.writable === false) + this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; + + // no more data can be written. + // But allow more writes to happen in this tick. + process.nextTick(this.end.bind(this)); +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} diff --git a/node_modules/readable-stream/lib/_stream_passthrough.js b/node_modules/readable-stream/lib/_stream_passthrough.js new file mode 100644 index 000000000..895ca50a1 --- /dev/null +++ b/node_modules/readable-stream/lib/_stream_passthrough.js @@ -0,0 +1,46 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +module.exports = PassThrough; + +var Transform = require('./_stream_transform'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); +}; diff --git a/node_modules/readable-stream/lib/_stream_readable.js b/node_modules/readable-stream/lib/_stream_readable.js new file mode 100644 index 000000000..630722099 --- /dev/null +++ b/node_modules/readable-stream/lib/_stream_readable.js @@ -0,0 +1,982 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +module.exports = Readable; + +/**/ +var isArray = require('isarray'); +/**/ + + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; + +/**/ +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +var Stream = require('stream'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var StringDecoder; + +util.inherits(Readable, Stream); + +function ReadableState(options, stream) { + options = options || {}; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = false; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // In streams that never have any data, and do push(null) right away, + // the consumer can miss the 'end' event if they do some I/O before + // consuming the stream. So, we don't emit('end') until some reading + // happens. + this.calledRead = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, becuase any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function(chunk, encoding) { + var state = this._readableState; + + if (typeof chunk === 'string' && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null || chunk === undefined) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); + + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) { + state.buffer.unshift(chunk); + } else { + state.reading = false; + state.buffer.push(chunk); + } + + if (state.needReadable) + emitReadable(stream); + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + + + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (n === null || isNaN(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } + + if (n <= 0) + return 0; + + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + var state = this._readableState; + state.calledRead = true; + var nOrig = n; + var ret; + + if (typeof n !== 'number' || n > 0) + state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && + state.needReadable && + (state.length >= state.highWaterMark || state.ended)) { + emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + ret = null; + + // In cases where the decoder did not receive enough data + // to produce a full chunk, then immediately received an + // EOF, state.buffer will contain [, ]. + // howMuchToRead will see this and coerce the amount to + // read to zero (because it's looking at the length of the + // first in state.buffer), and we'll end up here. + // + // This can only happen via state.decoder -- no other venue + // exists for pushing a zero-length chunk into state.buffer + // and triggering this behavior. In this case, we return our + // remaining data and end the stream, if appropriate. + if (state.length > 0 && state.decoder) { + ret = fromList(n, state); + state.length -= ret.length; + } + + if (state.length === 0) + endReadable(this); + + return ret; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + + // if we currently have less than the highWaterMark, then also read some + if (state.length - n <= state.highWaterMark) + doRead = true; + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) + doRead = false; + + if (doRead) { + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) + state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + } + + // If _read called its callback synchronously, then `reading` + // will be false, and we need to re-evaluate how much data we + // can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); + + if (n > 0) + ret = fromList(n, state); + else + ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; + + // If we happened to read() exactly the remaining amount in the + // buffer, and the EOF has been seen at this point, then make sure + // that we emit 'end' on the very next tick. + if (state.ended && !state.endEmitted && state.length === 0) + endReadable(this); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // if we've ended and we have some data left, then emit + // 'readable' now to make sure it gets picked up. + if (state.length > 0) + emitReadable(stream); + else + endReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (state.emittedReadable) + return; + + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); +} + +function emitReadable_(stream) { + stream.emit('readable'); +} + + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function(n) { + this.emit('error', new Error('not implemented')); +}; + +Readable.prototype.pipe = function(dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + if (readable !== src) return; + cleanup(); + } + + function onend() { + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + function cleanup() { + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (!dest._writableState || dest._writableState.needDrain) + ondrain(); + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (isArray(dest._events.error)) + dest._events.error.unshift(onerror); + else + dest._events.error = [onerror, dest._events.error]; + + + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + // the handler that waits for readable events after all + // the data gets sucked out in flow. + // This would be easier to follow with a .once() handler + // in flow(), but that is too slow. + this.on('readable', pipeOnReadable); + + state.flowing = true; + process.nextTick(function() { + flow(src); + }); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var dest = this; + var state = src._readableState; + state.awaitDrain--; + if (state.awaitDrain === 0) + flow(src); + }; +} + +function flow(src) { + var state = src._readableState; + var chunk; + state.awaitDrain = 0; + + function write(dest, i, list) { + var written = dest.write(chunk); + if (false === written) { + state.awaitDrain++; + } + } + + while (state.pipesCount && null !== (chunk = src.read())) { + + if (state.pipesCount === 1) + write(state.pipes, 0, null); + else + forEach(state.pipes, write); + + src.emit('data', chunk); + + // if anyone needs a drain, then we have to wait for that. + if (state.awaitDrain > 0) + return; + } + + // if every destination was unpiped, either before entering this + // function, or in the while loop, then stop flowing. + // + // NB: This is a pretty rare edge case. + if (state.pipesCount === 0) { + state.flowing = false; + + // if there were data event listeners added, then switch to old mode. + if (EE.listenerCount(src, 'data') > 0) + emitDataEvents(src); + return; + } + + // at this point, no one needed a drain, so we just ran out of data + // on the next readable event, start it over again. + state.ranOut = true; +} + +function pipeOnReadable() { + if (this._readableState.ranOut) { + this._readableState.ranOut = false; + flow(this); + } +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) + return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) + return this; + + if (!dest) + dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + this.removeListener('readable', pipeOnReadable); + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + this.removeListener('readable', pipeOnReadable); + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function(ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + if (ev === 'data' && !this._readableState.flowing) + emitDataEvents(this); + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + this.read(0); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + emitDataEvents(this); + this.read(0); + this.emit('resume'); +}; + +Readable.prototype.pause = function() { + emitDataEvents(this, true); + this.emit('pause'); +}; + +function emitDataEvents(stream, startPaused) { + var state = stream._readableState; + + if (state.flowing) { + // https://github.com/isaacs/readable-stream/issues/16 + throw new Error('Cannot switch to old mode now.'); + } + + var paused = startPaused || false; + var readable = false; + + // convert to an old-style stream. + stream.readable = true; + stream.pipe = Stream.prototype.pipe; + stream.on = stream.addListener = Stream.prototype.on; + + stream.on('readable', function() { + readable = true; + + var c; + while (!paused && (null !== (c = stream.read()))) + stream.emit('data', c); + + if (c === null) { + readable = false; + stream._readableState.needReadable = true; + } + }); + + stream.pause = function() { + paused = true; + this.emit('pause'); + }; + + stream.resume = function() { + paused = false; + if (readable) + process.nextTick(function() { + stream.emit('readable'); + }); + else + this.read(0); + this.emit('resume'); + }; + + // now make it start, just in case it hadn't already. + stream.emit('readable'); +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function(stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + if (state.decoder) + chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + //if (state.objectMode && util.isNullOrUndefined(chunk)) + if (state.objectMode && (chunk === null || chunk === undefined)) + return; + else if (!state.objectMode && (!chunk || !chunk.length)) + return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (typeof stream[i] === 'function' && + typeof this[i] === 'undefined') { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function(ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted && state.calledRead) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf (xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} diff --git a/node_modules/readable-stream/lib/_stream_transform.js b/node_modules/readable-stream/lib/_stream_transform.js new file mode 100644 index 000000000..eb188df3e --- /dev/null +++ b/node_modules/readable-stream/lib/_stream_transform.js @@ -0,0 +1,210 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + var ts = this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + this.once('finish', function() { + if ('function' === typeof this._flush) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +Transform.prototype.push = function(chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function(chunk, encoding, cb) { + throw new Error('not implemented'); +}; + +Transform.prototype._write = function(chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || + rs.needReadable || + rs.length < rs.highWaterMark) + this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function(n) { + var ts = this._transformState; + + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var rs = stream._readableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} diff --git a/node_modules/readable-stream/lib/_stream_writable.js b/node_modules/readable-stream/lib/_stream_writable.js new file mode 100644 index 000000000..4bdaa4fa4 --- /dev/null +++ b/node_modules/readable-stream/lib/_stream_writable.js @@ -0,0 +1,386 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Stream = require('stream'); + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + options = options || {}; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, becuase any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.buffer = []; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; +} + +function Writable(options) { + var Duplex = require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); + valid = false; + } + return valid; +} + +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (Buffer.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (typeof cb !== 'function') + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) + ret = writeOrBuffer(this, state, chunk, encoding, cb); + + return ret; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + typeof chunk === 'string') { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + if (Buffer.isBuffer(chunk)) + encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; + + if (state.writing) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + cb(er); + }); + else + cb(er); + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) + onwriteError(stream, state, sync, er, cb); + else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(stream, state); + + if (!finished && !state.bufferProcessing && state.buffer.length) + clearBuffer(stream, state); + + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + cb(); + if (finished) + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + state.bufferProcessing = false; + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +Writable.prototype.end = function(chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (typeof chunk !== 'undefined' && chunk !== null) + this.write(chunk, encoding); + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + state.finished = true; + stream.emit('finish'); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} diff --git a/node_modules/readable-stream/package.json b/node_modules/readable-stream/package.json new file mode 100644 index 000000000..613ccb8e6 --- /dev/null +++ b/node_modules/readable-stream/package.json @@ -0,0 +1,65 @@ +{ + "_from": "readable-stream@~1.0.2", + "_id": "readable-stream@1.0.34", + "_inBundle": false, + "_integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "_location": "/readable-stream", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "readable-stream@~1.0.2", + "name": "readable-stream", + "escapedName": "readable-stream", + "rawSpec": "~1.0.2", + "saveSpec": null, + "fetchSpec": "~1.0.2" + }, + "_requiredBy": [ + "/bl" + ], + "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "_shasum": "125820e34bc842d2f2aaafafe4c2916ee32c157c", + "_spec": "readable-stream@~1.0.2", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/bl", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "browser": { + "util": false + }, + "bugs": { + "url": "https://github.com/isaacs/readable-stream/issues" + }, + "bundleDependencies": false, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "deprecated": false, + "description": "Streams2, a user-land copy of the stream library from Node.js v0.10.x", + "devDependencies": { + "tap": "~0.2.6" + }, + "homepage": "https://github.com/isaacs/readable-stream#readme", + "keywords": [ + "readable", + "stream", + "pipe" + ], + "license": "MIT", + "main": "readable.js", + "name": "readable-stream", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/readable-stream.git" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "version": "1.0.34" +} diff --git a/node_modules/readable-stream/passthrough.js b/node_modules/readable-stream/passthrough.js new file mode 100644 index 000000000..27e8d8a55 --- /dev/null +++ b/node_modules/readable-stream/passthrough.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_passthrough.js") diff --git a/node_modules/readable-stream/readable.js b/node_modules/readable-stream/readable.js new file mode 100644 index 000000000..26511e87b --- /dev/null +++ b/node_modules/readable-stream/readable.js @@ -0,0 +1,11 @@ +var Stream = require('stream'); // hack to fix a circular dependency issue when used with browserify +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = Stream; +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); +if (!process.browser && process.env.READABLE_STREAM === 'disable') { + module.exports = require('stream'); +} diff --git a/node_modules/readable-stream/transform.js b/node_modules/readable-stream/transform.js new file mode 100644 index 000000000..5d482f078 --- /dev/null +++ b/node_modules/readable-stream/transform.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_transform.js") diff --git a/node_modules/readable-stream/writable.js b/node_modules/readable-stream/writable.js new file mode 100644 index 000000000..e1e9efdf3 --- /dev/null +++ b/node_modules/readable-stream/writable.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_writable.js") diff --git a/node_modules/string_decoder/.npmignore b/node_modules/string_decoder/.npmignore new file mode 100644 index 000000000..206320cc1 --- /dev/null +++ b/node_modules/string_decoder/.npmignore @@ -0,0 +1,2 @@ +build +test diff --git a/node_modules/string_decoder/LICENSE b/node_modules/string_decoder/LICENSE new file mode 100644 index 000000000..6de584a48 --- /dev/null +++ b/node_modules/string_decoder/LICENSE @@ -0,0 +1,20 @@ +Copyright Joyent, Inc. and other Node contributors. + +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/node_modules/string_decoder/README.md b/node_modules/string_decoder/README.md new file mode 100644 index 000000000..4d2aa0015 --- /dev/null +++ b/node_modules/string_decoder/README.md @@ -0,0 +1,7 @@ +**string_decoder.js** (`require('string_decoder')`) from Node.js core + +Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details. + +Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.** + +The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version. \ No newline at end of file diff --git a/node_modules/string_decoder/index.js b/node_modules/string_decoder/index.js new file mode 100644 index 000000000..b00e54fb7 --- /dev/null +++ b/node_modules/string_decoder/index.js @@ -0,0 +1,221 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Buffer = require('buffer').Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; + + +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} diff --git a/node_modules/string_decoder/package.json b/node_modules/string_decoder/package.json new file mode 100644 index 000000000..291c2ed9e --- /dev/null +++ b/node_modules/string_decoder/package.json @@ -0,0 +1,54 @@ +{ + "_from": "string_decoder@~0.10.x", + "_id": "string_decoder@0.10.31", + "_inBundle": false, + "_integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "_location": "/string_decoder", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "string_decoder@~0.10.x", + "name": "string_decoder", + "escapedName": "string_decoder", + "rawSpec": "~0.10.x", + "saveSpec": null, + "fetchSpec": "~0.10.x" + }, + "_requiredBy": [ + "/readable-stream", + "/through2/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "_shasum": "62e203bc41766c6c28c9fc84301dab1c5310fa94", + "_spec": "string_decoder@~0.10.x", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/readable-stream", + "bugs": { + "url": "https://github.com/rvagg/string_decoder/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "The string_decoder module from Node core", + "devDependencies": { + "tap": "~0.4.8" + }, + "homepage": "https://github.com/rvagg/string_decoder", + "keywords": [ + "string", + "decoder", + "browser", + "browserify" + ], + "license": "MIT", + "main": "index.js", + "name": "string_decoder", + "repository": { + "type": "git", + "url": "git://github.com/rvagg/string_decoder.git" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "version": "0.10.31" +} diff --git a/node_modules/strip-ansi/cli.js b/node_modules/strip-ansi/cli.js new file mode 100755 index 000000000..602ae00e8 --- /dev/null +++ b/node_modules/strip-ansi/cli.js @@ -0,0 +1,39 @@ +#!/usr/bin/env node +'use strict'; +var fs = require('fs'); +var pkg = require('./package.json'); +var strip = require('./'); +var input = process.argv[2]; + +function help() { + console.log([ + pkg.description, + '', + 'Usage', + ' $ strip-ansi > ', + ' $ cat | strip-ansi > ', + '', + 'Example', + ' $ strip-ansi unicorn.txt > unicorn-stripped.txt' + ].join('\n')); +} + +if (process.argv.indexOf('--help') !== -1) { + help(); + return; +} + +if (process.argv.indexOf('--version') !== -1) { + console.log(pkg.version); + return; +} + +if (input) { + process.stdout.write(strip(fs.readFileSync(input, 'utf8'))); + return; +} + +process.stdin.setEncoding('utf8'); +process.stdin.on('data', function (data) { + process.stdout.write(strip(data)); +}); diff --git a/node_modules/strip-ansi/index.js b/node_modules/strip-ansi/index.js new file mode 100644 index 000000000..099480fbf --- /dev/null +++ b/node_modules/strip-ansi/index.js @@ -0,0 +1,6 @@ +'use strict'; +var ansiRegex = require('ansi-regex')(); + +module.exports = function (str) { + return typeof str === 'string' ? str.replace(ansiRegex, '') : str; +}; diff --git a/node_modules/strip-ansi/package.json b/node_modules/strip-ansi/package.json new file mode 100644 index 000000000..9e411a433 --- /dev/null +++ b/node_modules/strip-ansi/package.json @@ -0,0 +1,88 @@ +{ + "_from": "strip-ansi@^0.3.0", + "_id": "strip-ansi@0.3.0", + "_inBundle": false, + "_integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "_location": "/strip-ansi", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "strip-ansi@^0.3.0", + "name": "strip-ansi", + "escapedName": "strip-ansi", + "rawSpec": "^0.3.0", + "saveSpec": null, + "fetchSpec": "^0.3.0" + }, + "_requiredBy": [ + "/chalk" + ], + "_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "_shasum": "25f48ea22ca79187f3174a4db8759347bb126220", + "_spec": "strip-ansi@^0.3.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bin": { + "strip-ansi": "cli.js" + }, + "bugs": { + "url": "https://github.com/sindresorhus/strip-ansi/issues" + }, + "bundleDependencies": false, + "dependencies": { + "ansi-regex": "^0.2.1" + }, + "deprecated": false, + "description": "Strip ANSI escape codes", + "devDependencies": { + "mocha": "*" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "cli.js" + ], + "homepage": "https://github.com/sindresorhus/strip-ansi#readme", + "keywords": [ + "strip", + "trim", + "remove", + "ansi", + "styles", + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "tty", + "escape", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "license": "MIT", + "name": "strip-ansi", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/strip-ansi.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "0.3.0" +} diff --git a/node_modules/strip-ansi/readme.md b/node_modules/strip-ansi/readme.md new file mode 100644 index 000000000..5477079d0 --- /dev/null +++ b/node_modules/strip-ansi/readme.md @@ -0,0 +1,43 @@ +# strip-ansi [![Build Status](https://travis-ci.org/sindresorhus/strip-ansi.svg?branch=master)](https://travis-ci.org/sindresorhus/strip-ansi) + +> Strip [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code) + + +## Install + +```sh +$ npm install --save strip-ansi +``` + + +## Usage + +```js +var stripAnsi = require('strip-ansi'); + +stripAnsi('\x1b[4mcake\x1b[0m'); +//=> 'cake' +``` + + +## CLI + +```sh +$ npm install --global strip-ansi +``` + +```sh +$ strip-ansi --help + +Usage + $ strip-ansi > + $ cat | strip-ansi > + +Example + $ strip-ansi unicorn.txt > unicorn-stripped.txt +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/supports-color/browser.js b/node_modules/supports-color/browser.js new file mode 100644 index 000000000..ae7c87b17 --- /dev/null +++ b/node_modules/supports-color/browser.js @@ -0,0 +1,2 @@ +'use strict'; +module.exports = false; diff --git a/node_modules/supports-color/index.js b/node_modules/supports-color/index.js new file mode 100644 index 000000000..a5d9331df --- /dev/null +++ b/node_modules/supports-color/index.js @@ -0,0 +1,115 @@ +'use strict'; +const os = require('os'); +const hasFlag = require('has-flag'); + +const env = process.env; + +const support = level => { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +}; + +let supportLevel = (() => { + if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + return 0; + } + + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + + if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + return 1; + } + + if (process.stdout && !process.stdout.isTTY) { + return 0; + } + + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return 2; + } + + return 1; + } + + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + + return 0; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Hyper': + return 3; + case 'Apple_Terminal': + return 2; + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + if (env.TERM === 'dumb') { + return 0; + } + + return 0; +})(); + +if ('FORCE_COLOR' in env) { + supportLevel = parseInt(env.FORCE_COLOR, 10) === 0 ? 0 : (supportLevel || 1); +} + +module.exports = process && support(supportLevel); diff --git a/node_modules/supports-color/license b/node_modules/supports-color/license new file mode 100644 index 000000000..e7af2f771 --- /dev/null +++ b/node_modules/supports-color/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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/node_modules/supports-color/package.json b/node_modules/supports-color/package.json new file mode 100644 index 000000000..a715a21bd --- /dev/null +++ b/node_modules/supports-color/package.json @@ -0,0 +1,85 @@ +{ + "_from": "supports-color@4.4.0", + "_id": "supports-color@4.4.0", + "_inBundle": false, + "_integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "_location": "/supports-color", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "supports-color@4.4.0", + "name": "supports-color", + "escapedName": "supports-color", + "rawSpec": "4.4.0", + "saveSpec": null, + "fetchSpec": "4.4.0" + }, + "_requiredBy": [ + "/mocha" + ], + "_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "_shasum": "883f7ddabc165142b2a61427f3352ded195d1a3e", + "_spec": "supports-color@4.4.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/mocha", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "browser": "browser.js", + "bugs": { + "url": "https://github.com/chalk/supports-color/issues" + }, + "bundleDependencies": false, + "dependencies": { + "has-flag": "^2.0.0" + }, + "deprecated": false, + "description": "Detect whether a terminal supports color", + "devDependencies": { + "ava": "*", + "import-fresh": "^2.0.0", + "xo": "*" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "index.js", + "browser.js" + ], + "homepage": "https://github.com/chalk/supports-color#readme", + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "ansi", + "styles", + "tty", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "support", + "supports", + "capability", + "detect", + "truecolor", + "16m" + ], + "license": "MIT", + "name": "supports-color", + "repository": { + "type": "git", + "url": "git+https://github.com/chalk/supports-color.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "4.4.0" +} diff --git a/node_modules/supports-color/readme.md b/node_modules/supports-color/readme.md new file mode 100644 index 000000000..3bef57db0 --- /dev/null +++ b/node_modules/supports-color/readme.md @@ -0,0 +1,66 @@ +# supports-color [![Build Status](https://travis-ci.org/chalk/supports-color.svg?branch=master)](https://travis-ci.org/chalk/supports-color) + +> Detect whether a terminal supports color + + +## Install + +``` +$ npm install supports-color +``` + + +## Usage + +```js +const supportsColor = require('supports-color'); + +if (supportsColor) { + console.log('Terminal supports color'); +} + +if (supportsColor.has256) { + console.log('Terminal supports 256 colors'); +} + +if (supportsColor.has16m) { + console.log('Terminal supports 16 million colors (truecolor)'); +} +``` + + +## API + +Returns an `Object`, or `false` if color is not supported. + +The returned object specifies a level of support for color through a `.level` property and a corresponding flag: + +- `.level = 1` and `.hasBasic = true`: Basic color support (16 colors) +- `.level = 2` and `.has256 = true`: 256 color support +- `.level = 3` and `.has16m = true`: Truecolor support (16 million colors) + + +## Info + +It obeys the `--color` and `--no-color` CLI flags. + +Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. + +Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. + + +## Related + +- [supports-color-cli](https://github.com/chalk/supports-color-cli) - CLI for this module +- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right + + +## Maintainers + +- [Sindre Sorhus](https://github.com/sindresorhus) +- [Josh Junon](https://github.com/qix-) + + +## License + +MIT diff --git a/node_modules/through2/.jshintrc b/node_modules/through2/.jshintrc new file mode 100644 index 000000000..c8ef3ca40 --- /dev/null +++ b/node_modules/through2/.jshintrc @@ -0,0 +1,59 @@ +{ + "predef": [ ] + , "bitwise": false + , "camelcase": false + , "curly": false + , "eqeqeq": false + , "forin": false + , "immed": false + , "latedef": false + , "noarg": true + , "noempty": true + , "nonew": true + , "plusplus": false + , "quotmark": true + , "regexp": false + , "undef": true + , "unused": true + , "strict": false + , "trailing": true + , "maxlen": 120 + , "asi": true + , "boss": true + , "debug": true + , "eqnull": true + , "esnext": true + , "evil": true + , "expr": true + , "funcscope": false + , "globalstrict": false + , "iterator": false + , "lastsemic": true + , "laxbreak": true + , "laxcomma": true + , "loopfunc": true + , "multistr": false + , "onecase": false + , "proto": false + , "regexdash": false + , "scripturl": true + , "smarttabs": false + , "shadow": false + , "sub": true + , "supernew": false + , "validthis": true + , "browser": true + , "couch": false + , "devel": false + , "dojo": false + , "mootools": false + , "node": true + , "nonstandard": true + , "prototypejs": false + , "rhino": false + , "worker": true + , "wsh": false + , "nomen": false + , "onevar": false + , "passfail": false +} \ No newline at end of file diff --git a/node_modules/through2/.npmignore b/node_modules/through2/.npmignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/node_modules/through2/.npmignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/node_modules/through2/.travis.yml b/node_modules/through2/.travis.yml new file mode 100644 index 000000000..cece8c63c --- /dev/null +++ b/node_modules/through2/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - "0.8" + - "0.10" + - "0.11" +branches: + only: + - master +notifications: + email: + - rod@vagg.org +script: npm test \ No newline at end of file diff --git a/node_modules/through2/LICENSE b/node_modules/through2/LICENSE new file mode 100644 index 000000000..f6a0029de --- /dev/null +++ b/node_modules/through2/LICENSE @@ -0,0 +1,39 @@ +Copyright 2013, Rod Vagg (the "Original Author") +All rights reserved. + +MIT +no-false-attribs 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. + +Distributions of all or part of the Software intended to be used +by the recipients as they would use the unmodified Software, +containing modifications that substantially alter, remove, or +disable functionality of the Software, outside of the documented +configuration mechanisms provided by the Software, shall be +modified such that the Original Author's bug reporting email +addresses and urls are either replaced with the contact information +of the parties responsible for the changes, or removed entirely. + +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. + + +Except where noted, this license applies to any and all software +programs and associated documentation files created by the +Original Author, when distributed with the Software. \ No newline at end of file diff --git a/node_modules/through2/README.md b/node_modules/through2/README.md new file mode 100644 index 000000000..b85a79034 --- /dev/null +++ b/node_modules/through2/README.md @@ -0,0 +1,107 @@ +# through2 + +[![Build Status](https://secure.travis-ci.org/rvagg/through2.png)](http://travis-ci.org/rvagg/through2) + +[![NPM](https://nodei.co/npm/through2.png?compact=true)](https://nodei.co/npm/through2/) + +[![david-dm](https://david-dm.org/rvagg/through2.png)](https://david-dm.org/rvagg/through2/) +[![david-dm](https://david-dm.org/rvagg/through2/dev-status.png)](https://david-dm.org/rvagg/through2#info=devDependencies/) + +**A tiny wrapper around Node streams.Transform (Streams2) to avoid explicit subclassing noise** + +Inspired by [Dominic Tarr](https://github.com/dominictarr)'s [through](https://github.com/dominictarr/through) in that it's so much easier to make a stream out of a function than it is to set up the prototype chain properly: `through(function (chunk) { ... })`. + +```js +fs.createReadStream('ex.txt') + .pipe(through2(function (chunk, enc, callback) { + for (var i = 0; i < chunk.length; i++) + if (chunk[i] == 97) + chunk[i] = 122 // swap 'a' for 'z' + this.push(chunk) + callback() + })) + .pipe(fs.createWriteStream('out.txt')) +``` + +Or object streams: + +```js +var all = [] +fs.createReadStream('data.csv') + .pipe(csv2()) + .pipe(through2({ objectMode: true }, function (chunk, enc, callback) { + var data = { + name : chunk[0] + , address : chunk[3] + , phone : chunk[10] + } + this.push(data) + callback() + })) + .on('data', function (data) { + all.push(data) + }) + .on('end', function () { + doSomethingSpecial(all) + }) +``` + +## API + +through2([ options, ] [ transformFunction ] [, flushFunction ]) + +Consult the **[stream.Transform](http://nodejs.org/docs/latest/api/stream.html#stream_class_stream_transform)** documentation for the exact rules of the `transformFunction` (i.e. `this._transform`) and the optional `flushFunction` (i.e. `this._flush`). + +### options + +The options argument is optional and is passed straight through to `stream.Transform`. So you can use `objectMode:true` if you are processing non-binary streams. + +The `options` argument is first, unlike standard convention, because if I'm passing in an anonymous function then I'd prefer for the options argument to not get lost at the end of the call: + +```js +fs.createReadStream('/tmp/important.dat') + .pipe(through2({ objectMode: true, allowHalfOpen: false }, function (chunk, enc, cb) { + this.push(new Buffer('wut?')) + cb() + }) + .pipe(fs.createWriteStream('/tmp/wut.txt')) +``` + +### transformFunction + +The `transformFunction` must have the following signature: `function (chunk, encoding, callback) {}`. A minimal implementation should call the `callback` function to indicate that the transformation is done, even if that transformation means discarding the chunk. + +To queue a new chunk, call `this.push(chunk)`—this can be called as many times as required before the `callback()` if you have multiple pieces to send on. + +If you **do not provide a `transformFunction`** then you will get a simple simple pass-through stream. + +### flushFunction + +The optional `flushFunction` is provided as the last argument (2nd or 3rd, depending on whether you've supplied options) is called just prior to the stream ending. Can be used to finish up any processing that may be in progress. + +through2.ctor([ options, ] transformFunction[, flushFunction ]) + +Instead of returning a `stream.Transform` instance, `through2.ctor()` returns a **constructor** for a custom Transform. This is useful when you want to use the same transform logic in multiple instances. + +```js +var FToC = through2.ctor({objectMode: true}, function (record, encoding, callback) { + if (record.temp != null && record.unit = "F") { + record.temp = ( ( record.temp - 32 ) * 5 ) / 9 + record.unit = "C" + } + this.push(record) + callback() +}) + +// Create instances of FToC like so: +var converter = new FToC() +// Or: +var converter = FToC() +// Or specify/override options when you instantiate, if you prefer: +var converter = FToC({objectMode: true}) + +``` + +## License + +**through2** is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. \ No newline at end of file diff --git a/node_modules/through2/node_modules/readable-stream/.npmignore b/node_modules/through2/node_modules/readable-stream/.npmignore new file mode 100644 index 000000000..38344f87a --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/.npmignore @@ -0,0 +1,5 @@ +build/ +test/ +examples/ +fs.js +zlib.js \ No newline at end of file diff --git a/node_modules/through2/node_modules/readable-stream/LICENSE b/node_modules/through2/node_modules/readable-stream/LICENSE new file mode 100644 index 000000000..e3d4e695a --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/LICENSE @@ -0,0 +1,18 @@ +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +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/node_modules/through2/node_modules/readable-stream/README.md b/node_modules/through2/node_modules/readable-stream/README.md new file mode 100644 index 000000000..e46b82390 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/README.md @@ -0,0 +1,15 @@ +# readable-stream + +***Node-core streams for userland*** + +[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/) +[![NPM](https://nodei.co/npm-dl/readable-stream.png&months=6&height=3)](https://nodei.co/npm/readable-stream/) + +This package is a mirror of the Streams2 and Streams3 implementations in Node-core. + +If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core. + +**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12. + +**readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `"~1.1.0"` + diff --git a/node_modules/through2/node_modules/readable-stream/duplex.js b/node_modules/through2/node_modules/readable-stream/duplex.js new file mode 100644 index 000000000..ca807af87 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/duplex.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_duplex.js") diff --git a/node_modules/through2/node_modules/readable-stream/float.patch b/node_modules/through2/node_modules/readable-stream/float.patch new file mode 100644 index 000000000..b984607a4 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/float.patch @@ -0,0 +1,923 @@ +diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js +index c5a741c..a2e0d8e 100644 +--- a/lib/_stream_duplex.js ++++ b/lib/_stream_duplex.js +@@ -26,8 +26,8 @@ + + module.exports = Duplex; + var util = require('util'); +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('./_stream_readable'); ++var Writable = require('./_stream_writable'); + + util.inherits(Duplex, Readable); + +diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js +index a5e9864..330c247 100644 +--- a/lib/_stream_passthrough.js ++++ b/lib/_stream_passthrough.js +@@ -25,7 +25,7 @@ + + module.exports = PassThrough; + +-var Transform = require('_stream_transform'); ++var Transform = require('./_stream_transform'); + var util = require('util'); + util.inherits(PassThrough, Transform); + +diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js +index 0c3fe3e..90a8298 100644 +--- a/lib/_stream_readable.js ++++ b/lib/_stream_readable.js +@@ -23,10 +23,34 @@ module.exports = Readable; + Readable.ReadableState = ReadableState; + + var EE = require('events').EventEmitter; ++if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { ++ return emitter.listeners(type).length; ++}; ++ ++if (!global.setImmediate) global.setImmediate = function setImmediate(fn) { ++ return setTimeout(fn, 0); ++}; ++if (!global.clearImmediate) global.clearImmediate = function clearImmediate(i) { ++ return clearTimeout(i); ++}; ++ + var Stream = require('stream'); + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + var StringDecoder; +-var debug = util.debuglog('stream'); ++var debug; ++if (util.debuglog) ++ debug = util.debuglog('stream'); ++else try { ++ debug = require('debuglog')('stream'); ++} catch (er) { ++ debug = function() {}; ++} + + util.inherits(Readable, Stream); + +@@ -380,7 +404,7 @@ function chunkInvalid(state, chunk) { + + + function onEofChunk(stream, state) { +- if (state.decoder && !state.ended) { ++ if (state.decoder && !state.ended && state.decoder.end) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); +diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js +index b1f9fcc..b0caf57 100644 +--- a/lib/_stream_transform.js ++++ b/lib/_stream_transform.js +@@ -64,8 +64,14 @@ + + module.exports = Transform; + +-var Duplex = require('_stream_duplex'); ++var Duplex = require('./_stream_duplex'); + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + util.inherits(Transform, Duplex); + + +diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js +index ba2e920..f49288b 100644 +--- a/lib/_stream_writable.js ++++ b/lib/_stream_writable.js +@@ -27,6 +27,12 @@ module.exports = Writable; + Writable.WritableState = WritableState; + + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + var Stream = require('stream'); + + util.inherits(Writable, Stream); +@@ -119,7 +125,7 @@ function WritableState(options, stream) { + function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. +- if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) ++ if (!(this instanceof Writable) && !(this instanceof require('./_stream_duplex'))) + return new Writable(options); + + this._writableState = new WritableState(options, this); +diff --git a/test/simple/test-stream-big-push.js b/test/simple/test-stream-big-push.js +index e3787e4..8cd2127 100644 +--- a/test/simple/test-stream-big-push.js ++++ b/test/simple/test-stream-big-push.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + var str = 'asdfasdfasdfasdfasdf'; + + var r = new stream.Readable({ +diff --git a/test/simple/test-stream-end-paused.js b/test/simple/test-stream-end-paused.js +index bb73777..d40efc7 100644 +--- a/test/simple/test-stream-end-paused.js ++++ b/test/simple/test-stream-end-paused.js +@@ -25,7 +25,7 @@ var gotEnd = false; + + // Make sure we don't miss the end event for paused 0-length streams + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var stream = new Readable(); + var calledRead = false; + stream._read = function() { +diff --git a/test/simple/test-stream-pipe-after-end.js b/test/simple/test-stream-pipe-after-end.js +index b46ee90..0be8366 100644 +--- a/test/simple/test-stream-pipe-after-end.js ++++ b/test/simple/test-stream-pipe-after-end.js +@@ -22,8 +22,8 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var util = require('util'); + + util.inherits(TestReadable, Readable); +diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js +deleted file mode 100644 +index f689358..0000000 +--- a/test/simple/test-stream-pipe-cleanup.js ++++ /dev/null +@@ -1,122 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// 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. +- +-// This test asserts that Stream.prototype.pipe does not leave listeners +-// hanging on the source or dest. +- +-var common = require('../common'); +-var stream = require('stream'); +-var assert = require('assert'); +-var util = require('util'); +- +-function Writable() { +- this.writable = true; +- this.endCalls = 0; +- stream.Stream.call(this); +-} +-util.inherits(Writable, stream.Stream); +-Writable.prototype.end = function() { +- this.endCalls++; +-}; +- +-Writable.prototype.destroy = function() { +- this.endCalls++; +-}; +- +-function Readable() { +- this.readable = true; +- stream.Stream.call(this); +-} +-util.inherits(Readable, stream.Stream); +- +-function Duplex() { +- this.readable = true; +- Writable.call(this); +-} +-util.inherits(Duplex, Writable); +- +-var i = 0; +-var limit = 100; +- +-var w = new Writable(); +- +-var r; +- +-for (i = 0; i < limit; i++) { +- r = new Readable(); +- r.pipe(w); +- r.emit('end'); +-} +-assert.equal(0, r.listeners('end').length); +-assert.equal(limit, w.endCalls); +- +-w.endCalls = 0; +- +-for (i = 0; i < limit; i++) { +- r = new Readable(); +- r.pipe(w); +- r.emit('close'); +-} +-assert.equal(0, r.listeners('close').length); +-assert.equal(limit, w.endCalls); +- +-w.endCalls = 0; +- +-r = new Readable(); +- +-for (i = 0; i < limit; i++) { +- w = new Writable(); +- r.pipe(w); +- w.emit('close'); +-} +-assert.equal(0, w.listeners('close').length); +- +-r = new Readable(); +-w = new Writable(); +-var d = new Duplex(); +-r.pipe(d); // pipeline A +-d.pipe(w); // pipeline B +-assert.equal(r.listeners('end').length, 2); // A.onend, A.cleanup +-assert.equal(r.listeners('close').length, 2); // A.onclose, A.cleanup +-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup +-assert.equal(d.listeners('close').length, 3); // A.cleanup, B.onclose, B.cleanup +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 1); // B.cleanup +- +-r.emit('end'); +-assert.equal(d.endCalls, 1); +-assert.equal(w.endCalls, 0); +-assert.equal(r.listeners('end').length, 0); +-assert.equal(r.listeners('close').length, 0); +-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup +-assert.equal(d.listeners('close').length, 2); // B.onclose, B.cleanup +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 1); // B.cleanup +- +-d.emit('end'); +-assert.equal(d.endCalls, 1); +-assert.equal(w.endCalls, 1); +-assert.equal(r.listeners('end').length, 0); +-assert.equal(r.listeners('close').length, 0); +-assert.equal(d.listeners('end').length, 0); +-assert.equal(d.listeners('close').length, 0); +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 0); +diff --git a/test/simple/test-stream-pipe-error-handling.js b/test/simple/test-stream-pipe-error-handling.js +index c5d724b..c7d6b7d 100644 +--- a/test/simple/test-stream-pipe-error-handling.js ++++ b/test/simple/test-stream-pipe-error-handling.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var Stream = require('stream').Stream; ++var Stream = require('../../').Stream; + + (function testErrorListenerCatches() { + var source = new Stream(); +diff --git a/test/simple/test-stream-pipe-event.js b/test/simple/test-stream-pipe-event.js +index cb9d5fe..56f8d61 100644 +--- a/test/simple/test-stream-pipe-event.js ++++ b/test/simple/test-stream-pipe-event.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common'); +-var stream = require('stream'); ++var stream = require('../../'); + var assert = require('assert'); + var util = require('util'); + +diff --git a/test/simple/test-stream-push-order.js b/test/simple/test-stream-push-order.js +index f2e6ec2..a5c9bf9 100644 +--- a/test/simple/test-stream-push-order.js ++++ b/test/simple/test-stream-push-order.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var assert = require('assert'); + + var s = new Readable({ +diff --git a/test/simple/test-stream-push-strings.js b/test/simple/test-stream-push-strings.js +index 06f43dc..1701a9a 100644 +--- a/test/simple/test-stream-push-strings.js ++++ b/test/simple/test-stream-push-strings.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var util = require('util'); + + util.inherits(MyStream, Readable); +diff --git a/test/simple/test-stream-readable-event.js b/test/simple/test-stream-readable-event.js +index ba6a577..a8e6f7b 100644 +--- a/test/simple/test-stream-readable-event.js ++++ b/test/simple/test-stream-readable-event.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + (function first() { + // First test, not reading when the readable is added. +diff --git a/test/simple/test-stream-readable-flow-recursion.js b/test/simple/test-stream-readable-flow-recursion.js +index 2891ad6..11689ba 100644 +--- a/test/simple/test-stream-readable-flow-recursion.js ++++ b/test/simple/test-stream-readable-flow-recursion.js +@@ -27,7 +27,7 @@ var assert = require('assert'); + // more data continuously, but without triggering a nextTick + // warning or RangeError. + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + // throw an error if we trigger a nextTick warning. + process.throwDeprecation = true; +diff --git a/test/simple/test-stream-unshift-empty-chunk.js b/test/simple/test-stream-unshift-empty-chunk.js +index 0c96476..7827538 100644 +--- a/test/simple/test-stream-unshift-empty-chunk.js ++++ b/test/simple/test-stream-unshift-empty-chunk.js +@@ -24,7 +24,7 @@ var assert = require('assert'); + + // This test verifies that stream.unshift(Buffer(0)) or + // stream.unshift('') does not set state.reading=false. +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + var r = new Readable(); + var nChunks = 10; +diff --git a/test/simple/test-stream-unshift-read-race.js b/test/simple/test-stream-unshift-read-race.js +index 83fd9fa..17c18aa 100644 +--- a/test/simple/test-stream-unshift-read-race.js ++++ b/test/simple/test-stream-unshift-read-race.js +@@ -29,7 +29,7 @@ var assert = require('assert'); + // 3. push() after the EOF signaling null is an error. + // 4. _read() is not called after pushing the EOF null chunk. + +-var stream = require('stream'); ++var stream = require('../../'); + var hwm = 10; + var r = stream.Readable({ highWaterMark: hwm }); + var chunks = 10; +@@ -51,7 +51,14 @@ r._read = function(n) { + + function push(fast) { + assert(!pushedNull, 'push() after null push'); +- var c = pos >= data.length ? null : data.slice(pos, pos + n); ++ var c; ++ if (pos >= data.length) ++ c = null; ++ else { ++ if (n + pos > data.length) ++ n = data.length - pos; ++ c = data.slice(pos, pos + n); ++ } + pushedNull = c === null; + if (fast) { + pos += n; +diff --git a/test/simple/test-stream-writev.js b/test/simple/test-stream-writev.js +index 5b49e6e..b5321f3 100644 +--- a/test/simple/test-stream-writev.js ++++ b/test/simple/test-stream-writev.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var stream = require('stream'); ++var stream = require('../../'); + + var queue = []; + for (var decode = 0; decode < 2; decode++) { +diff --git a/test/simple/test-stream2-basic.js b/test/simple/test-stream2-basic.js +index 3814bf0..248c1be 100644 +--- a/test/simple/test-stream2-basic.js ++++ b/test/simple/test-stream2-basic.js +@@ -21,7 +21,7 @@ + + + var common = require('../common.js'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-compatibility.js b/test/simple/test-stream2-compatibility.js +index 6cdd4e9..f0fa84b 100644 +--- a/test/simple/test-stream2-compatibility.js ++++ b/test/simple/test-stream2-compatibility.js +@@ -21,7 +21,7 @@ + + + var common = require('../common.js'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-finish-pipe.js b/test/simple/test-stream2-finish-pipe.js +index 39b274f..006a19b 100644 +--- a/test/simple/test-stream2-finish-pipe.js ++++ b/test/simple/test-stream2-finish-pipe.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var stream = require('stream'); ++var stream = require('../../'); + var Buffer = require('buffer').Buffer; + + var r = new stream.Readable(); +diff --git a/test/simple/test-stream2-fs.js b/test/simple/test-stream2-fs.js +deleted file mode 100644 +index e162406..0000000 +--- a/test/simple/test-stream2-fs.js ++++ /dev/null +@@ -1,72 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// Permission is hereby granted, free of charge, to any person obtaining a +-// copy of this software and associated documentation files (the +-// "Software"), to deal in the Software without restriction, including +-// without limitation the rights to use, copy, modify, merge, publish, +-// distribute, sublicense, and/or sell copies of the Software, and to permit +-// persons to whom the Software is furnished to do so, subject to the +-// following conditions: +-// +-// The above copyright notice and this permission notice shall be included +-// in all copies or substantial portions of the Software. +-// +-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +-// USE OR OTHER DEALINGS IN THE SOFTWARE. +- +- +-var common = require('../common.js'); +-var R = require('_stream_readable'); +-var assert = require('assert'); +- +-var fs = require('fs'); +-var FSReadable = fs.ReadStream; +- +-var path = require('path'); +-var file = path.resolve(common.fixturesDir, 'x1024.txt'); +- +-var size = fs.statSync(file).size; +- +-var expectLengths = [1024]; +- +-var util = require('util'); +-var Stream = require('stream'); +- +-util.inherits(TestWriter, Stream); +- +-function TestWriter() { +- Stream.apply(this); +- this.buffer = []; +- this.length = 0; +-} +- +-TestWriter.prototype.write = function(c) { +- this.buffer.push(c.toString()); +- this.length += c.length; +- return true; +-}; +- +-TestWriter.prototype.end = function(c) { +- if (c) this.buffer.push(c.toString()); +- this.emit('results', this.buffer); +-} +- +-var r = new FSReadable(file); +-var w = new TestWriter(); +- +-w.on('results', function(res) { +- console.error(res, w.length); +- assert.equal(w.length, size); +- var l = 0; +- assert.deepEqual(res.map(function (c) { +- return c.length; +- }), expectLengths); +- console.log('ok'); +-}); +- +-r.pipe(w); +diff --git a/test/simple/test-stream2-httpclient-response-end.js b/test/simple/test-stream2-httpclient-response-end.js +deleted file mode 100644 +index 15cffc2..0000000 +--- a/test/simple/test-stream2-httpclient-response-end.js ++++ /dev/null +@@ -1,52 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// Permission is hereby granted, free of charge, to any person obtaining a +-// copy of this software and associated documentation files (the +-// "Software"), to deal in the Software without restriction, including +-// without limitation the rights to use, copy, modify, merge, publish, +-// distribute, sublicense, and/or sell copies of the Software, and to permit +-// persons to whom the Software is furnished to do so, subject to the +-// following conditions: +-// +-// The above copyright notice and this permission notice shall be included +-// in all copies or substantial portions of the Software. +-// +-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +-// USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-var common = require('../common.js'); +-var assert = require('assert'); +-var http = require('http'); +-var msg = 'Hello'; +-var readable_event = false; +-var end_event = false; +-var server = http.createServer(function(req, res) { +- res.writeHead(200, {'Content-Type': 'text/plain'}); +- res.end(msg); +-}).listen(common.PORT, function() { +- http.get({port: common.PORT}, function(res) { +- var data = ''; +- res.on('readable', function() { +- console.log('readable event'); +- readable_event = true; +- data += res.read(); +- }); +- res.on('end', function() { +- console.log('end event'); +- end_event = true; +- assert.strictEqual(msg, data); +- server.close(); +- }); +- }); +-}); +- +-process.on('exit', function() { +- assert(readable_event); +- assert(end_event); +-}); +- +diff --git a/test/simple/test-stream2-large-read-stall.js b/test/simple/test-stream2-large-read-stall.js +index 2fbfbca..667985b 100644 +--- a/test/simple/test-stream2-large-read-stall.js ++++ b/test/simple/test-stream2-large-read-stall.js +@@ -30,7 +30,7 @@ var PUSHSIZE = 20; + var PUSHCOUNT = 1000; + var HWM = 50; + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var r = new Readable({ + highWaterMark: HWM + }); +@@ -39,23 +39,23 @@ var rs = r._readableState; + r._read = push; + + r.on('readable', function() { +- console.error('>> readable'); ++ //console.error('>> readable'); + do { +- console.error(' > read(%d)', READSIZE); ++ //console.error(' > read(%d)', READSIZE); + var ret = r.read(READSIZE); +- console.error(' < %j (%d remain)', ret && ret.length, rs.length); ++ //console.error(' < %j (%d remain)', ret && ret.length, rs.length); + } while (ret && ret.length === READSIZE); + +- console.error('<< after read()', +- ret && ret.length, +- rs.needReadable, +- rs.length); ++ //console.error('<< after read()', ++ // ret && ret.length, ++ // rs.needReadable, ++ // rs.length); + }); + + var endEmitted = false; + r.on('end', function() { + endEmitted = true; +- console.error('end'); ++ //console.error('end'); + }); + + var pushes = 0; +@@ -64,11 +64,11 @@ function push() { + return; + + if (pushes++ === PUSHCOUNT) { +- console.error(' push(EOF)'); ++ //console.error(' push(EOF)'); + return r.push(null); + } + +- console.error(' push #%d', pushes); ++ //console.error(' push #%d', pushes); + if (r.push(new Buffer(PUSHSIZE))) + setTimeout(push); + } +diff --git a/test/simple/test-stream2-objects.js b/test/simple/test-stream2-objects.js +index 3e6931d..ff47d89 100644 +--- a/test/simple/test-stream2-objects.js ++++ b/test/simple/test-stream2-objects.js +@@ -21,8 +21,8 @@ + + + var common = require('../common.js'); +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var assert = require('assert'); + + // tiny node-tap lookalike. +diff --git a/test/simple/test-stream2-pipe-error-handling.js b/test/simple/test-stream2-pipe-error-handling.js +index cf7531c..e3f3e4e 100644 +--- a/test/simple/test-stream2-pipe-error-handling.js ++++ b/test/simple/test-stream2-pipe-error-handling.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + + (function testErrorListenerCatches() { + var count = 1000; +diff --git a/test/simple/test-stream2-pipe-error-once-listener.js b/test/simple/test-stream2-pipe-error-once-listener.js +index 5e8e3cb..53b2616 100755 +--- a/test/simple/test-stream2-pipe-error-once-listener.js ++++ b/test/simple/test-stream2-pipe-error-once-listener.js +@@ -24,7 +24,7 @@ var common = require('../common.js'); + var assert = require('assert'); + + var util = require('util'); +-var stream = require('stream'); ++var stream = require('../../'); + + + var Read = function() { +diff --git a/test/simple/test-stream2-push.js b/test/simple/test-stream2-push.js +index b63edc3..eb2b0e9 100644 +--- a/test/simple/test-stream2-push.js ++++ b/test/simple/test-stream2-push.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var stream = require('stream'); ++var stream = require('../../'); + var Readable = stream.Readable; + var Writable = stream.Writable; + var assert = require('assert'); +diff --git a/test/simple/test-stream2-read-sync-stack.js b/test/simple/test-stream2-read-sync-stack.js +index e8a7305..9740a47 100644 +--- a/test/simple/test-stream2-read-sync-stack.js ++++ b/test/simple/test-stream2-read-sync-stack.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var r = new Readable(); + var N = 256 * 1024; + +diff --git a/test/simple/test-stream2-readable-empty-buffer-no-eof.js b/test/simple/test-stream2-readable-empty-buffer-no-eof.js +index cd30178..4b1659d 100644 +--- a/test/simple/test-stream2-readable-empty-buffer-no-eof.js ++++ b/test/simple/test-stream2-readable-empty-buffer-no-eof.js +@@ -22,10 +22,9 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + test1(); +-test2(); + + function test1() { + var r = new Readable(); +@@ -88,31 +87,3 @@ function test1() { + console.log('ok'); + }); + } +- +-function test2() { +- var r = new Readable({ encoding: 'base64' }); +- var reads = 5; +- r._read = function(n) { +- if (!reads--) +- return r.push(null); // EOF +- else +- return r.push(new Buffer('x')); +- }; +- +- var results = []; +- function flow() { +- var chunk; +- while (null !== (chunk = r.read())) +- results.push(chunk + ''); +- } +- r.on('readable', flow); +- r.on('end', function() { +- results.push('EOF'); +- }); +- flow(); +- +- process.on('exit', function() { +- assert.deepEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]); +- console.log('ok'); +- }); +-} +diff --git a/test/simple/test-stream2-readable-from-list.js b/test/simple/test-stream2-readable-from-list.js +index 7c96ffe..04a96f5 100644 +--- a/test/simple/test-stream2-readable-from-list.js ++++ b/test/simple/test-stream2-readable-from-list.js +@@ -21,7 +21,7 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var fromList = require('_stream_readable')._fromList; ++var fromList = require('../../lib/_stream_readable')._fromList; + + // tiny node-tap lookalike. + var tests = []; +diff --git a/test/simple/test-stream2-readable-legacy-drain.js b/test/simple/test-stream2-readable-legacy-drain.js +index 675da8e..51fd3d5 100644 +--- a/test/simple/test-stream2-readable-legacy-drain.js ++++ b/test/simple/test-stream2-readable-legacy-drain.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Stream = require('stream'); ++var Stream = require('../../'); + var Readable = Stream.Readable; + + var r = new Readable(); +diff --git a/test/simple/test-stream2-readable-non-empty-end.js b/test/simple/test-stream2-readable-non-empty-end.js +index 7314ae7..c971898 100644 +--- a/test/simple/test-stream2-readable-non-empty-end.js ++++ b/test/simple/test-stream2-readable-non-empty-end.js +@@ -21,7 +21,7 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var Readable = require('_stream_readable'); ++var Readable = require('../../lib/_stream_readable'); + + var len = 0; + var chunks = new Array(10); +diff --git a/test/simple/test-stream2-readable-wrap-empty.js b/test/simple/test-stream2-readable-wrap-empty.js +index 2e5cf25..fd8a3dc 100644 +--- a/test/simple/test-stream2-readable-wrap-empty.js ++++ b/test/simple/test-stream2-readable-wrap-empty.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); ++var Readable = require('../../lib/_stream_readable'); + var EE = require('events').EventEmitter; + + var oldStream = new EE(); +diff --git a/test/simple/test-stream2-readable-wrap.js b/test/simple/test-stream2-readable-wrap.js +index 90eea01..6b177f7 100644 +--- a/test/simple/test-stream2-readable-wrap.js ++++ b/test/simple/test-stream2-readable-wrap.js +@@ -22,8 +22,8 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var EE = require('events').EventEmitter; + + var testRuns = 0, completedRuns = 0; +diff --git a/test/simple/test-stream2-set-encoding.js b/test/simple/test-stream2-set-encoding.js +index 5d2c32a..685531b 100644 +--- a/test/simple/test-stream2-set-encoding.js ++++ b/test/simple/test-stream2-set-encoding.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var util = require('util'); + + // tiny node-tap lookalike. +diff --git a/test/simple/test-stream2-transform.js b/test/simple/test-stream2-transform.js +index 9c9ddd8..a0cacc6 100644 +--- a/test/simple/test-stream2-transform.js ++++ b/test/simple/test-stream2-transform.js +@@ -21,8 +21,8 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var PassThrough = require('_stream_passthrough'); +-var Transform = require('_stream_transform'); ++var PassThrough = require('../../').PassThrough; ++var Transform = require('../../').Transform; + + // tiny node-tap lookalike. + var tests = []; +diff --git a/test/simple/test-stream2-unpipe-drain.js b/test/simple/test-stream2-unpipe-drain.js +index d66dc3c..365b327 100644 +--- a/test/simple/test-stream2-unpipe-drain.js ++++ b/test/simple/test-stream2-unpipe-drain.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + var crypto = require('crypto'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js +index 99f8746..17c92ae 100644 +--- a/test/simple/test-stream2-unpipe-leak.js ++++ b/test/simple/test-stream2-unpipe-leak.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + + var chunk = new Buffer('hallo'); + +diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js +index 704100c..209c3a6 100644 +--- a/test/simple/test-stream2-writable.js ++++ b/test/simple/test-stream2-writable.js +@@ -20,8 +20,8 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var W = require('_stream_writable'); +-var D = require('_stream_duplex'); ++var W = require('../../').Writable; ++var D = require('../../').Duplex; + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream3-pause-then-read.js b/test/simple/test-stream3-pause-then-read.js +index b91bde3..2f72c15 100644 +--- a/test/simple/test-stream3-pause-then-read.js ++++ b/test/simple/test-stream3-pause-then-read.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var stream = require('stream'); ++var stream = require('../../'); + var Readable = stream.Readable; + var Writable = stream.Writable; + diff --git a/node_modules/through2/node_modules/readable-stream/lib/_stream_duplex.js b/node_modules/through2/node_modules/readable-stream/lib/_stream_duplex.js new file mode 100644 index 000000000..b513d61a9 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/lib/_stream_duplex.js @@ -0,0 +1,89 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +module.exports = Duplex; + +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} +/**/ + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +forEach(objectKeys(Writable.prototype), function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); + +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) + this.readable = false; + + if (options && options.writable === false) + this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; + + // no more data can be written. + // But allow more writes to happen in this tick. + process.nextTick(this.end.bind(this)); +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} diff --git a/node_modules/through2/node_modules/readable-stream/lib/_stream_passthrough.js b/node_modules/through2/node_modules/readable-stream/lib/_stream_passthrough.js new file mode 100644 index 000000000..895ca50a1 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/lib/_stream_passthrough.js @@ -0,0 +1,46 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +module.exports = PassThrough; + +var Transform = require('./_stream_transform'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); +}; diff --git a/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js b/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js new file mode 100644 index 000000000..19ab35889 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js @@ -0,0 +1,951 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +module.exports = Readable; + +/**/ +var isArray = require('isarray'); +/**/ + + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; + +/**/ +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +var Stream = require('stream'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var StringDecoder; + + +/**/ +var debug = require('util'); +if (debug && debug.debuglog) { + debug = debug.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + + +util.inherits(Readable, Stream); + +function ReadableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.readableObjectMode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + var Duplex = require('./_stream_duplex'); + + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function(chunk, encoding) { + var state = this._readableState; + + if (util.isString(chunk) && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (util.isNullOrUndefined(chunk)) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); + + if (!addToFront) + state.reading = false; + + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) + state.buffer.unshift(chunk); + else + state.buffer.push(chunk); + + if (state.needReadable) + emitReadable(stream); + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + + + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || util.isNull(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } + + if (n <= 0) + return 0; + + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + debug('read', n); + var state = this._readableState; + var nOrig = n; + + if (!util.isNumber(n) || n > 0) + state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && + state.needReadable && + (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) + endReadable(this); + else + emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) + endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } + + if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) + state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + } + + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); + + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; + + if (util.isNull(ret)) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended && state.length === 0) + endReadable(this); + + if (!util.isNull(ret)) + this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function(n) { + this.emit('error', new Error('not implemented')); +}; + +Readable.prototype.pipe = function(dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && + (!dest._writableState || dest._writableState.needDrain)) + ondrain(); + } + + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + if (false === ret) { + debug('false write response, pause', + src._readableState.awaitDrain); + src._readableState.awaitDrain++; + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (isArray(dest._events.error)) + dest._events.error.unshift(onerror); + else + dest._events.error = [onerror, dest._events.error]; + + + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) + state.awaitDrain--; + if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) + return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) + return this; + + if (!dest) + dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function(ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + // If listening to data, and it has not explicitly been paused, + // then call resume to start the flow of data on the next tick. + if (ev === 'data' && false !== this._readableState.flowing) { + this.resume(); + } + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + var self = this; + process.nextTick(function() { + debug('readable nexttick read 0'); + self.read(0); + }); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + if (!state.reading) { + debug('resume read 0'); + this.read(0); + } + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(function() { + resume_(stream, state); + }); + } +} + +function resume_(stream, state) { + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) + stream.read(0); +} + +Readable.prototype.pause = function() { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); + } +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function(stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + debug('wrapped data'); + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function(ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf (xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} diff --git a/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js b/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js new file mode 100644 index 000000000..905c5e450 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js @@ -0,0 +1,209 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (!util.isNullOrUndefined(data)) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + this.once('prefinish', function() { + if (util.isFunction(this._flush)) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +Transform.prototype.push = function(chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function(chunk, encoding, cb) { + throw new Error('not implemented'); +}; + +Transform.prototype._write = function(chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || + rs.needReadable || + rs.length < rs.highWaterMark) + this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function(n) { + var ts = this._transformState; + + if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} diff --git a/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js b/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js new file mode 100644 index 000000000..db8539cd5 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js @@ -0,0 +1,477 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Stream = require('stream'); + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.writableObjectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.buffer = []; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; +} + +function Writable(options) { + var Duplex = require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); + valid = false; + } + return valid; +} + +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (util.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (!util.isFunction(cb)) + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function() { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function() { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && + !state.corked && + !state.finished && + !state.bufferProcessing && + state.buffer.length) + clearBuffer(this, state); + } +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + util.isString(chunk)) { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + if (util.isBuffer(chunk)) + encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; + + if (state.writing || state.corked) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, false, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) + stream._writev(chunk, state.onwrite); + else + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + state.pendingcb--; + cb(er); + }); + else { + state.pendingcb--; + cb(er); + } + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) + onwriteError(stream, state, sync, er, cb); + else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(stream, state); + + if (!finished && + !state.corked && + !state.bufferProcessing && + state.buffer.length) { + clearBuffer(stream, state); + } + + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + + if (stream._writev && state.buffer.length > 1) { + // Fast case, write everything using _writev() + var cbs = []; + for (var c = 0; c < state.buffer.length; c++) + cbs.push(state.buffer[c].callback); + + // count the one we are adding, as well. + // TODO(isaacs) clean this up + state.pendingcb++; + doWrite(stream, state, true, state.length, state.buffer, '', function(err) { + for (var i = 0; i < cbs.length; i++) { + state.pendingcb--; + cbs[i](err); + } + }); + + // Clear buffer + state.buffer = []; + } else { + // Slow case, write chunks one-by-one + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; + } + + state.bufferProcessing = false; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); + +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function(chunk, encoding, cb) { + var state = this._writableState; + + if (util.isFunction(chunk)) { + cb = chunk; + chunk = null; + encoding = null; + } else if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (!util.isNullOrUndefined(chunk)) + this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else + prefinish(stream, state); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} diff --git a/node_modules/through2/node_modules/readable-stream/package.json b/node_modules/through2/node_modules/readable-stream/package.json new file mode 100644 index 000000000..04d120ca0 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/package.json @@ -0,0 +1,65 @@ +{ + "_from": "readable-stream@~1.1.9", + "_id": "readable-stream@1.1.14", + "_inBundle": false, + "_integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "_location": "/through2/readable-stream", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "readable-stream@~1.1.9", + "name": "readable-stream", + "escapedName": "readable-stream", + "rawSpec": "~1.1.9", + "saveSpec": null, + "fetchSpec": "~1.1.9" + }, + "_requiredBy": [ + "/through2" + ], + "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "_shasum": "7cf4c54ef648e3813084c636dd2079e166c081d9", + "_spec": "readable-stream@~1.1.9", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/through2", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "browser": { + "util": false + }, + "bugs": { + "url": "https://github.com/isaacs/readable-stream/issues" + }, + "bundleDependencies": false, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "deprecated": false, + "description": "Streams3, a user-land copy of the stream library from Node.js v0.11.x", + "devDependencies": { + "tap": "~0.2.6" + }, + "homepage": "https://github.com/isaacs/readable-stream#readme", + "keywords": [ + "readable", + "stream", + "pipe" + ], + "license": "MIT", + "main": "readable.js", + "name": "readable-stream", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/readable-stream.git" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "version": "1.1.14" +} diff --git a/node_modules/through2/node_modules/readable-stream/passthrough.js b/node_modules/through2/node_modules/readable-stream/passthrough.js new file mode 100644 index 000000000..27e8d8a55 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/passthrough.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_passthrough.js") diff --git a/node_modules/through2/node_modules/readable-stream/readable.js b/node_modules/through2/node_modules/readable-stream/readable.js new file mode 100644 index 000000000..2a8b5c6b5 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/readable.js @@ -0,0 +1,10 @@ +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = require('stream'); +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); +if (!process.browser && process.env.READABLE_STREAM === 'disable') { + module.exports = require('stream'); +} diff --git a/node_modules/through2/node_modules/readable-stream/transform.js b/node_modules/through2/node_modules/readable-stream/transform.js new file mode 100644 index 000000000..5d482f078 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/transform.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_transform.js") diff --git a/node_modules/through2/node_modules/readable-stream/writable.js b/node_modules/through2/node_modules/readable-stream/writable.js new file mode 100644 index 000000000..e1e9efdf3 --- /dev/null +++ b/node_modules/through2/node_modules/readable-stream/writable.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_writable.js") diff --git a/node_modules/through2/package.json b/node_modules/through2/package.json new file mode 100644 index 000000000..232ba1d6b --- /dev/null +++ b/node_modules/through2/package.json @@ -0,0 +1,68 @@ +{ + "_from": "through2@~0.2.1", + "_id": "through2@0.2.3", + "_inBundle": false, + "_integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", + "_location": "/through2", + "_phantomChildren": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "_requested": { + "type": "range", + "registry": true, + "raw": "through2@~0.2.1", + "name": "through2", + "escapedName": "through2", + "rawSpec": "~0.2.1", + "saveSpec": null, + "fetchSpec": "~0.2.1" + }, + "_requiredBy": [ + "/pygmentize-bundled" + ], + "_resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", + "_shasum": "eb3284da4ea311b6cc8ace3653748a52abf25a3f", + "_spec": "through2@~0.2.1", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/pygmentize-bundled", + "author": { + "name": "Rod Vagg", + "email": "r@va.gg", + "url": "https://github.com/rvagg" + }, + "bugs": { + "url": "https://github.com/rvagg/through2/issues" + }, + "bundleDependencies": false, + "dependencies": { + "readable-stream": "~1.1.9", + "xtend": "~2.1.1" + }, + "deprecated": false, + "description": "A tiny wrapper around Node streams2 Transform to avoid explicit subclassing noise", + "devDependencies": { + "bl": "~0.4.1", + "stream-spigot": "~2.1.2", + "tape": "~1.1.1" + }, + "homepage": "https://github.com/rvagg/through2#readme", + "keywords": [ + "stream", + "streams2", + "through", + "transform" + ], + "license": "MIT", + "main": "through2.js", + "name": "through2", + "repository": { + "type": "git", + "url": "git+https://github.com/rvagg/through2.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "0.2.3" +} diff --git a/node_modules/through2/test.js b/node_modules/through2/test.js new file mode 100644 index 000000000..b2120de46 --- /dev/null +++ b/node_modules/through2/test.js @@ -0,0 +1,314 @@ +const test = require('tape') + , through2 = require('./') + , crypto = require('crypto') + , bl = require('bl') + , spigot = require('stream-spigot') + +test('plain through', function (t) { + var th2 = through2(function (chunk, enc, callback) { + if (!this._i) + this._i = 97 // 'a' + else + this._i++ + var b = new Buffer(chunk.length) + for (var i = 0; i < chunk.length; i++) + b[i] = this._i + this.push(b) + callback() + }) + + th2.pipe(bl(function (err, b) { + var s = b.toString('ascii') + t.equal('aaaaaaaaaabbbbbcccccccccc', s, 'got transformed string') + t.end() + })) + + th2.write(crypto.randomBytes(10)) + th2.write(crypto.randomBytes(5)) + th2.write(crypto.randomBytes(10)) + th2.end() +}) + +test('pipeable through', function (t) { + var th2 = through2(function (chunk, enc, callback) { + if (!this._i) + this._i = 97 // 'a' + else + this._i++ + var b = new Buffer(chunk.length) + for (var i = 0; i < chunk.length; i++) + b[i] = this._i + this.push(b) + callback() + }) + + th2.pipe(bl(function (err, b) { + var s = b.toString('ascii') + // bl() acts like a proper streams2 stream and passes as much as it's + // asked for, so we really only get one write with such a small amount + // of data + t.equal(s, 'aaaaaaaaaaaaaaaaaaaaaaaaa', 'got transformed string') + t.end() + })) + + var bufs = bl() + bufs.append(crypto.randomBytes(10)) + bufs.append(crypto.randomBytes(5)) + bufs.append(crypto.randomBytes(10)) + bufs.pipe(th2) +}) + +test('object through', function (t) { + t.plan(3) + + var th2 = through2({ objectMode: true}, function (chunk, enc, callback) { + this.push({ out: chunk.in + 1 }) + callback() + }) + + var e = 0 + th2.on('data', function (o) { + t.deepEqual(o, { out: e === 0 ? 102 : e == 1 ? 203 : -99 }, 'got transformed object') + e++ + }) + + th2.write({ in: 101 }) + th2.write({ in: 202 }) + th2.write({ in: -100 }) + th2.end() +}) + +test('flushing through', function (t) { + var th2 = through2(function (chunk, enc, callback) { + if (!this._i) + this._i = 97 // 'a' + else + this._i++ + var b = new Buffer(chunk.length) + for (var i = 0; i < chunk.length; i++) + b[i] = this._i + this.push(b) + callback() + }, function (callback) { + this.push(new Buffer([ 101, 110, 100 ])) + callback() + }) + + th2.pipe(bl(function (err, b) { + var s = b.toString('ascii') + t.equal(s, 'aaaaaaaaaabbbbbccccccccccend', 'got transformed string') + t.end() + })) + + th2.write(crypto.randomBytes(10)) + th2.write(crypto.randomBytes(5)) + th2.write(crypto.randomBytes(10)) + th2.end() +}) + +test('plain through ctor', function (t) { + var Th2 = through2.ctor(function (chunk, enc, callback) { + if (!this._i) + this._i = 97 // 'a' + else + this._i++ + var b = new Buffer(chunk.length) + for (var i = 0; i < chunk.length; i++) + b[i] = this._i + this.push(b) + callback() + }) + + var th2 = new Th2() + + th2.pipe(bl(function (err, b) { + var s = b.toString('ascii') + t.equal('aaaaaaaaaabbbbbcccccccccc', s, 'got transformed string') + t.end() + })) + + th2.write(crypto.randomBytes(10)) + th2.write(crypto.randomBytes(5)) + th2.write(crypto.randomBytes(10)) + th2.end() +}) + +test('reuse through ctor', function (t) { + t.plan(4) + + var Th2 = through2.ctor(function (chunk, enc, callback) { + if (!this._i) { + t.ok(1, 'did not contain previous instance data (this._i)') + this._i = 97 // 'a' + } else + this._i++ + var b = new Buffer(chunk.length) + for (var i = 0; i < chunk.length; i++) + b[i] = this._i + this.push(b) + callback() + }) + + var th2 = Th2() + + th2.pipe(bl(function (err, b) { + var s = b.toString('ascii') + t.equal('aaaaaaaaaabbbbbcccccccccc', s, 'got transformed string') + + var newInstance = Th2() + newInstance.pipe(bl(function (err, b) { + var s = b.toString('ascii') + t.equal('aaaaaaabbbbccccccc', s, 'got transformed string') + })) + + newInstance.write(crypto.randomBytes(7)) + newInstance.write(crypto.randomBytes(4)) + newInstance.write(crypto.randomBytes(7)) + newInstance.end() + })) + + th2.write(crypto.randomBytes(10)) + th2.write(crypto.randomBytes(5)) + th2.write(crypto.randomBytes(10)) + th2.end() +}) + +test('object through ctor', function (t) { + t.plan(3) + + var Th2 = through2.ctor({ objectMode: true}, function (chunk, enc, callback) { + this.push({ out: chunk.in + 1 }) + callback() + }) + + var th2 = new Th2() + + var e = 0 + th2.on('data', function (o) { + t.deepEqual(o, { out: e === 0 ? 102 : e == 1 ? 203 : -99 }, 'got transformed object') + e++ + }) + + th2.write({ in: 101 }) + th2.write({ in: 202 }) + th2.write({ in: -100 }) + th2.end() +}) + +test('pipeable object through ctor', function (t) { + t.plan(4) + + var Th2 = through2.ctor({ objectMode: true}, function (record, enc, callback) { + if (record.temp != null && record.unit == 'F') { + record.temp = ( ( record.temp - 32 ) * 5 ) / 9 + record.unit = 'C' + } + this.push(record) + callback() + }) + + var th2 = Th2() + + var expect = [-19, -40, 100, 22] + th2.on('data', function (o) { + t.deepEqual(o, { temp: expect.shift(), unit: 'C' }, 'got transformed object') + }) + + spigot({objectMode: true}, [ + {temp: -2.2, unit: 'F'}, + {temp: -40, unit: 'F'}, + {temp: 212, unit: 'F'}, + {temp: 22, unit: 'C'} + ]).pipe(th2) +}) + +test('object through ctor override', function (t) { + t.plan(3) + + var Th2 = through2.ctor(function (chunk, enc, callback) { + this.push({ out: chunk.in + 1 }) + callback() + }) + + var th2 = Th2({objectMode: true}) + + var e = 0 + th2.on('data', function (o) { + t.deepEqual(o, { out: e === 0 ? 102 : e == 1 ? 203 : -99 }, 'got transformed object') + e++ + }) + + th2.write({ in: 101 }) + th2.write({ in: 202 }) + th2.write({ in: -100 }) + th2.end() +}) + +test('object settings available in transform', function (t) { + t.plan(6) + + var Th2 = through2.ctor({objectMode: true, peek: true}, function (chunk, enc, callback) { + t.ok(this.options.peek, "reading options from inside _transform") + this.push({ out: chunk.in + 1 }) + callback() + }) + + var th2 = Th2() + + var e = 0 + th2.on('data', function (o) { + t.deepEqual(o, { out: e === 0 ? 102 : e == 1 ? 203 : -99 }, 'got transformed object') + e++ + }) + + th2.write({ in: 101 }) + th2.write({ in: 202 }) + th2.write({ in: -100 }) + th2.end() +}) + +test('object settings available in transform override', function (t) { + t.plan(6) + + var Th2 = through2.ctor(function (chunk, enc, callback) { + t.ok(this.options.peek, "reading options from inside _transform") + this.push({ out: chunk.in + 1 }) + callback() + }) + + var th2 = Th2({objectMode: true, peek: true}) + + var e = 0 + th2.on('data', function (o) { + t.deepEqual(o, { out: e === 0 ? 102 : e == 1 ? 203 : -99 }, 'got transformed object') + e++ + }) + + th2.write({ in: 101 }) + th2.write({ in: 202 }) + th2.write({ in: -100 }) + th2.end() +}) + +test('object override extends options', function (t) { + t.plan(6) + + var Th2 = through2.ctor({objectMode: true}, function (chunk, enc, callback) { + t.ok(this.options.peek, "reading options from inside _transform") + this.push({ out: chunk.in + 1 }) + callback() + }) + + var th2 = Th2({peek: true}) + + var e = 0 + th2.on('data', function (o) { + t.deepEqual(o, { out: e === 0 ? 102 : e == 1 ? 203 : -99 }, 'got transformed object') + e++ + }) + + th2.write({ in: 101 }) + th2.write({ in: 202 }) + th2.write({ in: -100 }) + th2.end() +}) \ No newline at end of file diff --git a/node_modules/through2/through2.js b/node_modules/through2/through2.js new file mode 100644 index 000000000..0a88c82ed --- /dev/null +++ b/node_modules/through2/through2.js @@ -0,0 +1,42 @@ +const Transform = require('stream').Transform || require('readable-stream/transform') + , inherits = require('util').inherits + , xtend = require('xtend') + +function noop (chunk, enc, callback) { + callback(null, chunk) +} + +function ctor (options, transform, flush) { + if (typeof options == 'function') { + flush = transform + transform = options + options = {} + } + + if (typeof transform != 'function') + transform = noop + + function Through2 (override) { + if (!(this instanceof Through2)) + return new Through2(override) + + this.options = xtend(options, override) + Transform.call(this, this.options) + } + + inherits(Through2, Transform) + + Through2.prototype._transform = transform + + if (typeof flush == 'function') + Through2.prototype._flush = flush + + return Through2 +} + +function make (options, transform, flush) { + return ctor(options, transform, flush)() +} + +module.exports = make +module.exports.ctor = ctor \ No newline at end of file diff --git a/node_modules/type-detect/LICENSE b/node_modules/type-detect/LICENSE new file mode 100644 index 000000000..7ea799f0e --- /dev/null +++ b/node_modules/type-detect/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Jake Luer (http://alogicalparadox.com) + +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/node_modules/type-detect/README.md b/node_modules/type-detect/README.md new file mode 100644 index 000000000..d2c4cb7e5 --- /dev/null +++ b/node_modules/type-detect/README.md @@ -0,0 +1,228 @@ +

+ + ChaiJS type-detect + +

+
+

+ Improved typeof detection for node and the browser. +

+ +

+ + license:mit + + + tag:? + + + build:? + + + coverage:? + + + npm:? + + + dependencies:? + + + devDependencies:? + +
+ + + + + + + + + + + + + + +
Supported Browsers
Chrome Edge Firefox Safari IE
9, 10, 11
+
+ + Join the Slack chat + + + Join the Gitter chat + +

+ +## What is Type-Detect? + +Type Detect is a module which you can use to detect the type of a given object. It returns a string representation of the object's type, either using [`typeof`](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-typeof-operator) or [`@@toStringTag`](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-symbol.tostringtag). It also normalizes some object names for consistency among browsers. + +## Why? + +The `typeof` operator will only specify primitive values; everything else is `"object"` (including `null`, arrays, regexps, etc). Many developers use `Object.prototype.toString()` - which is a fine alternative and returns many more types (null returns `[object Null]`, Arrays as `[object Array]`, regexps as `[object RegExp]` etc). + +Sadly, `Object.prototype.toString` is slow, and buggy. By slow - we mean it is slower than `typeof`. By buggy - we mean that some values (like Promises, the global object, iterators, dataviews, a bunch of HTML elements) all report different things in different browsers. + +`type-detect` fixes all of the shortcomings with `Object.prototype.toString`. We have extra code to speed up checks of JS and DOM objects, as much as 20-30x faster for some values. `type-detect` also fixes any consistencies with these objects. + +## Installation + +### Node.js + +`type-detect` is available on [npm](http://npmjs.org). To install it, type: + + $ npm install type-detect + +### Browsers + +You can also use it within the browser; install via npm and use the `type-detect.js` file found within the download. For example: + +```html + +``` + +## Usage + +The primary export of `type-detect` is function that can serve as a replacement for `typeof`. The results of this function will be more specific than that of native `typeof`. + +```js +var type = require('type-detect'); +``` + +#### array + +```js +assert(type([]) === 'Array'); +assert(type(new Array()) === 'Array'); +``` + +#### regexp + +```js +assert(type(/a-z/gi) === 'RegExp'); +assert(type(new RegExp('a-z')) === 'RegExp'); +``` + +#### function + +```js +assert(type(function () {}) === 'function'); +``` + +#### arguments + +```js +(function () { + assert(type(arguments) === 'Arguments'); +})(); +``` + +#### date + +```js +assert(type(new Date) === 'Date'); +``` + +#### number + +```js +assert(type(1) === 'number'); +assert(type(1.234) === 'number'); +assert(type(-1) === 'number'); +assert(type(-1.234) === 'number'); +assert(type(Infinity) === 'number'); +assert(type(NaN) === 'number'); +assert(type(new Number(1)) === 'Number'); // note - the object version has a capital N +``` + +#### string + +```js +assert(type('hello world') === 'string'); +assert(type(new String('hello')) === 'String'); // note - the object version has a capital S +``` + +#### null + +```js +assert(type(null) === 'null'); +assert(type(undefined) !== 'null'); +``` + +#### undefined + +```js +assert(type(undefined) === 'undefined'); +assert(type(null) !== 'undefined'); +``` + +#### object + +```js +var Noop = function () {}; +assert(type({}) === 'Object'); +assert(type(Noop) !== 'Object'); +assert(type(new Noop) === 'Object'); +assert(type(new Object) === 'Object'); +``` + +#### ECMA6 Types + +All new ECMAScript 2015 objects are also supported, such as Promises and Symbols: + +```js +assert(type(new Map() === 'Map'); +assert(type(new WeakMap()) === 'WeakMap'); +assert(type(new Set()) === 'Set'); +assert(type(new WeakSet()) === 'WeakSet'); +assert(type(Symbol()) === 'symbol'); +assert(type(new Promise(callback) === 'Promise'); +assert(type(new Int8Array()) === 'Int8Array'); +assert(type(new Uint8Array()) === 'Uint8Array'); +assert(type(new UInt8ClampedArray()) === 'Uint8ClampedArray'); +assert(type(new Int16Array()) === 'Int16Array'); +assert(type(new Uint16Array()) === 'Uint16Array'); +assert(type(new Int32Array()) === 'Int32Array'); +assert(type(new UInt32Array()) === 'Uint32Array'); +assert(type(new Float32Array()) === 'Float32Array'); +assert(type(new Float64Array()) === 'Float64Array'); +assert(type(new ArrayBuffer()) === 'ArrayBuffer'); +assert(type(new DataView(arrayBuffer)) === 'DataView'); +``` + +Also, if you use `Symbol.toStringTag` to change an Objects return value of the `toString()` Method, `type()` will return this value, e.g: + +```js +var myObject = {}; +myObject[Symbol.toStringTag] = 'myCustomType'; +assert(type(myObject) === 'myCustomType'); +``` diff --git a/node_modules/type-detect/index.js b/node_modules/type-detect/index.js new file mode 100644 index 000000000..98a1e031c --- /dev/null +++ b/node_modules/type-detect/index.js @@ -0,0 +1,378 @@ +/* ! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ +const promiseExists = typeof Promise === 'function'; + +/* eslint-disable no-undef */ +const globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist + +const symbolExists = typeof Symbol !== 'undefined'; +const mapExists = typeof Map !== 'undefined'; +const setExists = typeof Set !== 'undefined'; +const weakMapExists = typeof WeakMap !== 'undefined'; +const weakSetExists = typeof WeakSet !== 'undefined'; +const dataViewExists = typeof DataView !== 'undefined'; +const symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; +const symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; +const setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; +const mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; +const setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); +const mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); +const arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; +const arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); +const stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; +const stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); +const toStringLeftSliceLength = 8; +const toStringRightSliceLength = -1; +/** + * ### typeOf (obj) + * + * Uses `Object.prototype.toString` to determine the type of an object, + * normalising behaviour across engine versions & well optimised. + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ +export default function typeDetect(obj) { + /* ! Speed optimisation + * Pre: + * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) + * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) + * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) + * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) + * function x 2,556,769 ops/sec ±1.73% (77 runs sampled) + * Post: + * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) + * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) + * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) + * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) + * function x 31,296,870 ops/sec ±0.96% (83 runs sampled) + */ + const typeofObj = typeof obj; + if (typeofObj !== 'object') { + return typeofObj; + } + + /* ! Speed optimisation + * Pre: + * null x 28,645,765 ops/sec ±1.17% (82 runs sampled) + * Post: + * null x 36,428,962 ops/sec ±1.37% (84 runs sampled) + */ + if (obj === null) { + return 'null'; + } + + /* ! Spec Conformance + * Test: `Object.prototype.toString.call(window)`` + * - Node === "[object global]" + * - Chrome === "[object global]" + * - Firefox === "[object Window]" + * - PhantomJS === "[object Window]" + * - Safari === "[object Window]" + * - IE 11 === "[object Window]" + * - IE Edge === "[object Window]" + * Test: `Object.prototype.toString.call(this)`` + * - Chrome Worker === "[object global]" + * - Firefox Worker === "[object DedicatedWorkerGlobalScope]" + * - Safari Worker === "[object DedicatedWorkerGlobalScope]" + * - IE 11 Worker === "[object WorkerGlobalScope]" + * - IE Edge Worker === "[object WorkerGlobalScope]" + */ + if (obj === globalObject) { + return 'global'; + } + + /* ! Speed optimisation + * Pre: + * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) + * Post: + * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) + */ + if ( + Array.isArray(obj) && + (symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) + ) { + return 'Array'; + } + + // Not caching existence of `window` and related properties due to potential + // for `window` to be unset before tests in quasi-browser environments. + if (typeof window === 'object' && window !== null) { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/browsers.html#location) + * WhatWG HTML$7.7.3 - The `Location` interface + * Test: `Object.prototype.toString.call(window.location)`` + * - IE <=11 === "[object Object]" + * - IE Edge <=13 === "[object Object]" + */ + if (typeof window.location === 'object' && obj === window.location) { + return 'Location'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#document) + * WhatWG HTML$3.1.1 - The `Document` object + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * WhatWG HTML states: + * > For historical reasons, Window objects must also have a + * > writable, configurable, non-enumerable property named + * > HTMLDocument whose value is the Document interface object. + * Test: `Object.prototype.toString.call(document)`` + * - Chrome === "[object HTMLDocument]" + * - Firefox === "[object HTMLDocument]" + * - Safari === "[object HTMLDocument]" + * - IE <=10 === "[object Document]" + * - IE 11 === "[object HTMLDocument]" + * - IE Edge <=13 === "[object HTMLDocument]" + */ + if (typeof window.document === 'object' && obj === window.document) { + return 'Document'; + } + + if (typeof window.navigator === 'object') { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray + * Test: `Object.prototype.toString.call(navigator.mimeTypes)`` + * - IE <=10 === "[object MSMimeTypesCollection]" + */ + if (typeof window.navigator.mimeTypes === 'object' && + obj === window.navigator.mimeTypes) { + return 'MimeTypeArray'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray + * Test: `Object.prototype.toString.call(navigator.plugins)`` + * - IE <=10 === "[object MSPluginsCollection]" + */ + if (typeof window.navigator.plugins === 'object' && + obj === window.navigator.plugins) { + return 'PluginArray'; + } + } + + if ((typeof window.HTMLElement === 'function' || + typeof window.HTMLElement === 'object') && + obj instanceof window.HTMLElement) { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` + * Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` + * - IE <=10 === "[object HTMLBlockElement]" + */ + if (obj.tagName === 'BLOCKQUOTE') { + return 'HTMLQuoteElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltabledatacellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('td')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj.tagName === 'TD') { + return 'HTMLTableDataCellElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltableheadercellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('th')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj.tagName === 'TH') { + return 'HTMLTableHeaderCellElement'; + } + } + } + + /* ! Speed optimisation + * Pre: + * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) + * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) + * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) + * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) + * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) + * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) + * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) + * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) + * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) + * Post: + * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) + * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) + * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) + * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) + * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) + * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) + * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) + * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) + * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) + */ + const stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); + if (typeof stringTag === 'string') { + return stringTag; + } + + const objPrototype = Object.getPrototypeOf(obj); + /* ! Speed optimisation + * Pre: + * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) + * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) + * Post: + * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) + * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) + */ + if (objPrototype === RegExp.prototype) { + return 'RegExp'; + } + + /* ! Speed optimisation + * Pre: + * date x 2,130,074 ops/sec ±4.42% (68 runs sampled) + * Post: + * date x 3,953,779 ops/sec ±1.35% (77 runs sampled) + */ + if (objPrototype === Date.prototype) { + return 'Date'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) + * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": + * Test: `Object.prototype.toString.call(Promise.resolve())`` + * - Chrome <=47 === "[object Object]" + * - Edge <=20 === "[object Object]" + * - Firefox 29-Latest === "[object Promise]" + * - Safari 7.1-Latest === "[object Promise]" + */ + if (promiseExists && objPrototype === Promise.prototype) { + return 'Promise'; + } + + /* ! Speed optimisation + * Pre: + * set x 2,222,186 ops/sec ±1.31% (82 runs sampled) + * Post: + * set x 4,545,879 ops/sec ±1.13% (83 runs sampled) + */ + if (setExists && objPrototype === Set.prototype) { + return 'Set'; + } + + /* ! Speed optimisation + * Pre: + * map x 2,396,842 ops/sec ±1.59% (81 runs sampled) + * Post: + * map x 4,183,945 ops/sec ±6.59% (82 runs sampled) + */ + if (mapExists && objPrototype === Map.prototype) { + return 'Map'; + } + + /* ! Speed optimisation + * Pre: + * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) + * Post: + * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) + */ + if (weakSetExists && objPrototype === WeakSet.prototype) { + return 'WeakSet'; + } + + /* ! Speed optimisation + * Pre: + * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) + * Post: + * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) + */ + if (weakMapExists && objPrototype === WeakMap.prototype) { + return 'WeakMap'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) + * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": + * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` + * - Edge <=13 === "[object Object]" + */ + if (dataViewExists && objPrototype === DataView.prototype) { + return 'DataView'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) + * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": + * Test: `Object.prototype.toString.call(new Map().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (mapExists && objPrototype === mapIteratorPrototype) { + return 'Map Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) + * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": + * Test: `Object.prototype.toString.call(new Set().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (setExists && objPrototype === setIteratorPrototype) { + return 'Set Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) + * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": + * Test: `Object.prototype.toString.call([][Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { + return 'Array Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) + * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": + * Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (stringIteratorExists && objPrototype === stringIteratorPrototype) { + return 'String Iterator'; + } + + /* ! Speed optimisation + * Pre: + * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) + * Post: + * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) + */ + if (objPrototype === null) { + return 'Object'; + } + + return Object + .prototype + .toString + .call(obj) + .slice(toStringLeftSliceLength, toStringRightSliceLength); +} diff --git a/node_modules/type-detect/package.json b/node_modules/type-detect/package.json new file mode 100644 index 000000000..f2e95042f --- /dev/null +++ b/node_modules/type-detect/package.json @@ -0,0 +1,169 @@ +{ + "_from": "type-detect@^4.0.0", + "_id": "type-detect@4.0.8", + "_inBundle": false, + "_integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "_location": "/type-detect", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "type-detect@^4.0.0", + "name": "type-detect", + "escapedName": "type-detect", + "rawSpec": "^4.0.0", + "saveSpec": null, + "fetchSpec": "^4.0.0" + }, + "_requiredBy": [ + "/chai", + "/deep-eql" + ], + "_resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "_shasum": "7646fb5f18871cfbb7749e69bd39a6388eb7450c", + "_spec": "type-detect@^4.0.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/chai", + "author": { + "name": "Jake Luer", + "email": "jake@alogicalparadox.com", + "url": "http://alogicalparadox.com" + }, + "bugs": { + "url": "https://github.com/chaijs/type-detect/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "Keith Cirkel", + "url": "https://github.com/keithamus" + }, + { + "name": "David Losert", + "url": "https://github.com/davelosert" + }, + { + "name": "Aleksey Shvayka", + "url": "https://github.com/shvaikalesh" + }, + { + "name": "Lucas Fernandes da Costa", + "url": "https://github.com/lucasfcosta" + }, + { + "name": "Grant Snodgrass", + "url": "https://github.com/meeber" + }, + { + "name": "Jeremy Tice", + "url": "https://github.com/jetpacmonkey" + }, + { + "name": "Edward Betts", + "url": "https://github.com/EdwardBetts" + }, + { + "name": "dvlsg", + "url": "https://github.com/dvlsg" + }, + { + "name": "Amila Welihinda", + "url": "https://github.com/amilajack" + }, + { + "name": "Jake Champion", + "url": "https://github.com/JakeChampion" + }, + { + "name": "Miroslav Bajtoš", + "url": "https://github.com/bajtos" + } + ], + "deprecated": false, + "description": "Improved typeof detection for node.js and the browser.", + "devDependencies": { + "@commitlint/cli": "^4.2.2", + "benchmark": "^2.1.0", + "buble": "^0.16.0", + "codecov": "^3.0.0", + "commitlint-config-angular": "^4.2.1", + "cross-env": "^5.1.1", + "eslint": "^4.10.0", + "eslint-config-strict": "^14.0.0", + "eslint-plugin-filenames": "^1.2.0", + "husky": "^0.14.3", + "karma": "^1.7.1", + "karma-chrome-launcher": "^2.2.0", + "karma-coverage": "^1.1.1", + "karma-detect-browsers": "^2.2.5", + "karma-edge-launcher": "^0.4.2", + "karma-firefox-launcher": "^1.0.1", + "karma-ie-launcher": "^1.0.0", + "karma-mocha": "^1.3.0", + "karma-opera-launcher": "^1.0.0", + "karma-safari-launcher": "^1.0.0", + "karma-safaritechpreview-launcher": "0.0.6", + "karma-sauce-launcher": "^1.2.0", + "mocha": "^4.0.1", + "nyc": "^11.3.0", + "rollup": "^0.50.0", + "rollup-plugin-buble": "^0.16.0", + "rollup-plugin-commonjs": "^8.2.6", + "rollup-plugin-istanbul": "^1.1.0", + "rollup-plugin-node-resolve": "^3.0.0", + "semantic-release": "^8.2.0", + "simple-assert": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "eslintConfig": { + "env": { + "es6": true + }, + "extends": [ + "strict/es6" + ], + "globals": { + "HTMLElement": false + }, + "rules": { + "complexity": 0, + "max-statements": 0, + "prefer-rest-params": 0 + } + }, + "files": [ + "index.js", + "type-detect.js" + ], + "homepage": "https://github.com/chaijs/type-detect#readme", + "keywords": [ + "type", + "typeof", + "types" + ], + "license": "MIT", + "main": "./type-detect.js", + "name": "type-detect", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/chaijs/type-detect.git" + }, + "scripts": { + "bench": "node bench", + "build": "rollup -c rollup.conf.js", + "commit-msg": "commitlint -x angular", + "lint": "eslint --ignore-path .gitignore .", + "posttest:browser": "npm run upload-coverage", + "posttest:node": "nyc report --report-dir \"coverage/node-$(node --version)\" --reporter=lcovonly && npm run upload-coverage", + "prepare": "cross-env NODE_ENV=production npm run build", + "pretest:browser": "cross-env NODE_ENV=test npm run build", + "pretest:node": "cross-env NODE_ENV=test npm run build", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "test": "npm run test:node && npm run test:browser", + "test:browser": "karma start --singleRun=true", + "test:node": "nyc mocha type-detect.test.js", + "upload-coverage": "codecov" + }, + "version": "4.0.8" +} diff --git a/node_modules/type-detect/type-detect.js b/node_modules/type-detect/type-detect.js new file mode 100644 index 000000000..2f5552525 --- /dev/null +++ b/node_modules/type-detect/type-detect.js @@ -0,0 +1,388 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.typeDetect = factory()); +}(this, (function () { 'use strict'; + +/* ! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ +var promiseExists = typeof Promise === 'function'; + +/* eslint-disable no-undef */ +var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist + +var symbolExists = typeof Symbol !== 'undefined'; +var mapExists = typeof Map !== 'undefined'; +var setExists = typeof Set !== 'undefined'; +var weakMapExists = typeof WeakMap !== 'undefined'; +var weakSetExists = typeof WeakSet !== 'undefined'; +var dataViewExists = typeof DataView !== 'undefined'; +var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; +var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; +var setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; +var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; +var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); +var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); +var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; +var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); +var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; +var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); +var toStringLeftSliceLength = 8; +var toStringRightSliceLength = -1; +/** + * ### typeOf (obj) + * + * Uses `Object.prototype.toString` to determine the type of an object, + * normalising behaviour across engine versions & well optimised. + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ +function typeDetect(obj) { + /* ! Speed optimisation + * Pre: + * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) + * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) + * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) + * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) + * function x 2,556,769 ops/sec ±1.73% (77 runs sampled) + * Post: + * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) + * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) + * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) + * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) + * function x 31,296,870 ops/sec ±0.96% (83 runs sampled) + */ + var typeofObj = typeof obj; + if (typeofObj !== 'object') { + return typeofObj; + } + + /* ! Speed optimisation + * Pre: + * null x 28,645,765 ops/sec ±1.17% (82 runs sampled) + * Post: + * null x 36,428,962 ops/sec ±1.37% (84 runs sampled) + */ + if (obj === null) { + return 'null'; + } + + /* ! Spec Conformance + * Test: `Object.prototype.toString.call(window)`` + * - Node === "[object global]" + * - Chrome === "[object global]" + * - Firefox === "[object Window]" + * - PhantomJS === "[object Window]" + * - Safari === "[object Window]" + * - IE 11 === "[object Window]" + * - IE Edge === "[object Window]" + * Test: `Object.prototype.toString.call(this)`` + * - Chrome Worker === "[object global]" + * - Firefox Worker === "[object DedicatedWorkerGlobalScope]" + * - Safari Worker === "[object DedicatedWorkerGlobalScope]" + * - IE 11 Worker === "[object WorkerGlobalScope]" + * - IE Edge Worker === "[object WorkerGlobalScope]" + */ + if (obj === globalObject) { + return 'global'; + } + + /* ! Speed optimisation + * Pre: + * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) + * Post: + * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) + */ + if ( + Array.isArray(obj) && + (symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) + ) { + return 'Array'; + } + + // Not caching existence of `window` and related properties due to potential + // for `window` to be unset before tests in quasi-browser environments. + if (typeof window === 'object' && window !== null) { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/browsers.html#location) + * WhatWG HTML$7.7.3 - The `Location` interface + * Test: `Object.prototype.toString.call(window.location)`` + * - IE <=11 === "[object Object]" + * - IE Edge <=13 === "[object Object]" + */ + if (typeof window.location === 'object' && obj === window.location) { + return 'Location'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#document) + * WhatWG HTML$3.1.1 - The `Document` object + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * WhatWG HTML states: + * > For historical reasons, Window objects must also have a + * > writable, configurable, non-enumerable property named + * > HTMLDocument whose value is the Document interface object. + * Test: `Object.prototype.toString.call(document)`` + * - Chrome === "[object HTMLDocument]" + * - Firefox === "[object HTMLDocument]" + * - Safari === "[object HTMLDocument]" + * - IE <=10 === "[object Document]" + * - IE 11 === "[object HTMLDocument]" + * - IE Edge <=13 === "[object HTMLDocument]" + */ + if (typeof window.document === 'object' && obj === window.document) { + return 'Document'; + } + + if (typeof window.navigator === 'object') { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray + * Test: `Object.prototype.toString.call(navigator.mimeTypes)`` + * - IE <=10 === "[object MSMimeTypesCollection]" + */ + if (typeof window.navigator.mimeTypes === 'object' && + obj === window.navigator.mimeTypes) { + return 'MimeTypeArray'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray + * Test: `Object.prototype.toString.call(navigator.plugins)`` + * - IE <=10 === "[object MSPluginsCollection]" + */ + if (typeof window.navigator.plugins === 'object' && + obj === window.navigator.plugins) { + return 'PluginArray'; + } + } + + if ((typeof window.HTMLElement === 'function' || + typeof window.HTMLElement === 'object') && + obj instanceof window.HTMLElement) { + /* ! Spec Conformance + * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) + * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` + * Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` + * - IE <=10 === "[object HTMLBlockElement]" + */ + if (obj.tagName === 'BLOCKQUOTE') { + return 'HTMLQuoteElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltabledatacellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('td')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj.tagName === 'TD') { + return 'HTMLTableDataCellElement'; + } + + /* ! Spec Conformance + * (https://html.spec.whatwg.org/#htmltableheadercellelement) + * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` + * Note: Most browsers currently adher to the W3C DOM Level 2 spec + * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) + * which suggests that browsers should use HTMLTableCellElement for + * both TD and TH elements. WhatWG separates these. + * Test: Object.prototype.toString.call(document.createElement('th')) + * - Chrome === "[object HTMLTableCellElement]" + * - Firefox === "[object HTMLTableCellElement]" + * - Safari === "[object HTMLTableCellElement]" + */ + if (obj.tagName === 'TH') { + return 'HTMLTableHeaderCellElement'; + } + } + } + + /* ! Speed optimisation + * Pre: + * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) + * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) + * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) + * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) + * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) + * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) + * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) + * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) + * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) + * Post: + * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) + * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) + * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) + * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) + * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) + * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) + * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) + * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) + * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) + */ + var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); + if (typeof stringTag === 'string') { + return stringTag; + } + + var objPrototype = Object.getPrototypeOf(obj); + /* ! Speed optimisation + * Pre: + * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) + * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) + * Post: + * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) + * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) + */ + if (objPrototype === RegExp.prototype) { + return 'RegExp'; + } + + /* ! Speed optimisation + * Pre: + * date x 2,130,074 ops/sec ±4.42% (68 runs sampled) + * Post: + * date x 3,953,779 ops/sec ±1.35% (77 runs sampled) + */ + if (objPrototype === Date.prototype) { + return 'Date'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) + * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": + * Test: `Object.prototype.toString.call(Promise.resolve())`` + * - Chrome <=47 === "[object Object]" + * - Edge <=20 === "[object Object]" + * - Firefox 29-Latest === "[object Promise]" + * - Safari 7.1-Latest === "[object Promise]" + */ + if (promiseExists && objPrototype === Promise.prototype) { + return 'Promise'; + } + + /* ! Speed optimisation + * Pre: + * set x 2,222,186 ops/sec ±1.31% (82 runs sampled) + * Post: + * set x 4,545,879 ops/sec ±1.13% (83 runs sampled) + */ + if (setExists && objPrototype === Set.prototype) { + return 'Set'; + } + + /* ! Speed optimisation + * Pre: + * map x 2,396,842 ops/sec ±1.59% (81 runs sampled) + * Post: + * map x 4,183,945 ops/sec ±6.59% (82 runs sampled) + */ + if (mapExists && objPrototype === Map.prototype) { + return 'Map'; + } + + /* ! Speed optimisation + * Pre: + * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) + * Post: + * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) + */ + if (weakSetExists && objPrototype === WeakSet.prototype) { + return 'WeakSet'; + } + + /* ! Speed optimisation + * Pre: + * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) + * Post: + * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) + */ + if (weakMapExists && objPrototype === WeakMap.prototype) { + return 'WeakMap'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) + * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": + * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` + * - Edge <=13 === "[object Object]" + */ + if (dataViewExists && objPrototype === DataView.prototype) { + return 'DataView'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) + * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": + * Test: `Object.prototype.toString.call(new Map().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (mapExists && objPrototype === mapIteratorPrototype) { + return 'Map Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) + * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": + * Test: `Object.prototype.toString.call(new Set().entries())`` + * - Edge <=13 === "[object Object]" + */ + if (setExists && objPrototype === setIteratorPrototype) { + return 'Set Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) + * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": + * Test: `Object.prototype.toString.call([][Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { + return 'Array Iterator'; + } + + /* ! Spec Conformance + * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) + * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": + * Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` + * - Edge <=13 === "[object Object]" + */ + if (stringIteratorExists && objPrototype === stringIteratorPrototype) { + return 'String Iterator'; + } + + /* ! Speed optimisation + * Pre: + * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) + * Post: + * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) + */ + if (objPrototype === null) { + return 'Object'; + } + + return Object + .prototype + .toString + .call(obj) + .slice(toStringLeftSliceLength, toStringRightSliceLength); +} + +return typeDetect; + +}))); diff --git a/node_modules/underscore/LICENSE b/node_modules/underscore/LICENSE new file mode 100644 index 000000000..ad0e71bc4 --- /dev/null +++ b/node_modules/underscore/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative +Reporters & Editors + +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/node_modules/underscore/README.md b/node_modules/underscore/README.md new file mode 100644 index 000000000..c2ba2590c --- /dev/null +++ b/node_modules/underscore/README.md @@ -0,0 +1,22 @@ + __ + /\ \ __ + __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ + /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ + \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ + \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ + \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ + \ \____/ + \/___/ + +Underscore.js is a utility-belt library for JavaScript that provides +support for the usual functional suspects (each, map, reduce, filter...) +without extending any core JavaScript objects. + +For Docs, License, Tests, and pre-packed downloads, see: +http://underscorejs.org + +Underscore is an open-sourced component of DocumentCloud: +https://github.com/documentcloud + +Many thanks to our contributors: +https://github.com/jashkenas/underscore/contributors diff --git a/node_modules/underscore/package.json b/node_modules/underscore/package.json new file mode 100644 index 000000000..2058bf071 --- /dev/null +++ b/node_modules/underscore/package.json @@ -0,0 +1,73 @@ +{ + "_from": "underscore@^1.7.0", + "_id": "underscore@1.8.3", + "_inBundle": false, + "_integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "_location": "/underscore", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "underscore@^1.7.0", + "name": "underscore", + "escapedName": "underscore", + "rawSpec": "^1.7.0", + "saveSpec": null, + "fetchSpec": "^1.7.0" + }, + "_requiredBy": [ + "/pryjs" + ], + "_resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "_shasum": "4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022", + "_spec": "underscore@^1.7.0", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/pryjs", + "author": { + "name": "Jeremy Ashkenas", + "email": "jeremy@documentcloud.org" + }, + "bugs": { + "url": "https://github.com/jashkenas/underscore/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "JavaScript's functional programming helper library.", + "devDependencies": { + "docco": "*", + "eslint": "0.6.x", + "karma": "~0.12.31", + "karma-qunit": "~0.1.4", + "qunit-cli": "~0.2.0", + "uglify-js": "2.4.x" + }, + "files": [ + "underscore.js", + "underscore-min.js", + "underscore-min.map", + "LICENSE" + ], + "homepage": "http://underscorejs.org", + "keywords": [ + "util", + "functional", + "server", + "client", + "browser" + ], + "license": "MIT", + "main": "underscore.js", + "name": "underscore", + "repository": { + "type": "git", + "url": "git://github.com/jashkenas/underscore.git" + }, + "scripts": { + "build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js", + "doc": "docco underscore.js", + "lint": "eslint underscore.js test/*.js", + "test": "npm run test-node && npm run lint", + "test-browser": "npm i karma-phantomjs-launcher && ./node_modules/karma/bin/karma start", + "test-node": "qunit-cli test/*.js" + }, + "version": "1.8.3" +} diff --git a/node_modules/underscore/underscore-min.js b/node_modules/underscore/underscore-min.js new file mode 100644 index 000000000..f01025b7b --- /dev/null +++ b/node_modules/underscore/underscore-min.js @@ -0,0 +1,6 @@ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); +//# sourceMappingURL=underscore-min.map \ No newline at end of file diff --git a/node_modules/underscore/underscore-min.map b/node_modules/underscore/underscore-min.map new file mode 100644 index 000000000..cf356bf9a --- /dev/null +++ b/node_modules/underscore/underscore-min.map @@ -0,0 +1 @@ +{"version":3,"file":"underscore-min.js","sources":["underscore.js"],"names":["createReduce","dir","iterator","obj","iteratee","memo","keys","index","length","currentKey","context","optimizeCb","isArrayLike","_","arguments","createPredicateIndexFinder","array","predicate","cb","getLength","createIndexFinder","predicateFind","sortedIndex","item","idx","i","Math","max","min","slice","call","isNaN","collectNonEnumProps","nonEnumIdx","nonEnumerableProps","constructor","proto","isFunction","prototype","ObjProto","prop","has","contains","push","root","this","previousUnderscore","ArrayProto","Array","Object","FuncProto","Function","toString","hasOwnProperty","nativeIsArray","isArray","nativeKeys","nativeBind","bind","nativeCreate","create","Ctor","_wrapped","exports","module","VERSION","func","argCount","value","other","collection","accumulator","apply","identity","isObject","matcher","property","Infinity","createAssigner","keysFunc","undefinedOnly","source","l","key","baseCreate","result","MAX_ARRAY_INDEX","pow","each","forEach","map","collect","results","reduce","foldl","inject","reduceRight","foldr","find","detect","findIndex","findKey","filter","select","list","reject","negate","every","all","some","any","includes","include","fromIndex","guard","values","indexOf","invoke","method","args","isFunc","pluck","where","attrs","findWhere","computed","lastComputed","shuffle","rand","set","shuffled","random","sample","n","sortBy","criteria","sort","left","right","a","b","group","behavior","groupBy","indexBy","countBy","toArray","size","partition","pass","fail","first","head","take","initial","last","rest","tail","drop","compact","flatten","input","shallow","strict","startIndex","output","isArguments","j","len","without","difference","uniq","unique","isSorted","isBoolean","seen","union","intersection","argsLength","zip","unzip","object","findLastIndex","low","high","mid","floor","lastIndexOf","range","start","stop","step","ceil","executeBound","sourceFunc","boundFunc","callingContext","self","TypeError","bound","concat","partial","boundArgs","position","bindAll","Error","memoize","hasher","cache","address","delay","wait","setTimeout","defer","throttle","options","timeout","previous","later","leading","now","remaining","clearTimeout","trailing","debounce","immediate","timestamp","callNow","wrap","wrapper","compose","after","times","before","once","hasEnumBug","propertyIsEnumerable","allKeys","mapObject","pairs","invert","functions","methods","names","extend","extendOwn","assign","pick","oiteratee","omit","String","defaults","props","clone","tap","interceptor","isMatch","eq","aStack","bStack","className","areArrays","aCtor","bCtor","pop","isEqual","isEmpty","isString","isElement","nodeType","type","name","Int8Array","isFinite","parseFloat","isNumber","isNull","isUndefined","noConflict","constant","noop","propertyOf","matches","accum","Date","getTime","escapeMap","&","<",">","\"","'","`","unescapeMap","createEscaper","escaper","match","join","testRegexp","RegExp","replaceRegexp","string","test","replace","escape","unescape","fallback","idCounter","uniqueId","prefix","id","templateSettings","evaluate","interpolate","noMatch","escapes","\\","\r","\n","
","
","escapeChar","template","text","settings","oldSettings","offset","variable","render","e","data","argument","chain","instance","_chain","mixin","valueOf","toJSON","define","amd"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/underscore/underscore.js b/node_modules/underscore/underscore.js new file mode 100644 index 000000000..b29332f94 --- /dev/null +++ b/node_modules/underscore/underscore.js @@ -0,0 +1,1548 @@ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); diff --git a/node_modules/wrappy/LICENSE b/node_modules/wrappy/LICENSE new file mode 100644 index 000000000..19129e315 --- /dev/null +++ b/node_modules/wrappy/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/node_modules/wrappy/README.md b/node_modules/wrappy/README.md new file mode 100644 index 000000000..98eab2522 --- /dev/null +++ b/node_modules/wrappy/README.md @@ -0,0 +1,36 @@ +# wrappy + +Callback wrapping utility + +## USAGE + +```javascript +var wrappy = require("wrappy") + +// var wrapper = wrappy(wrapperFunction) + +// make sure a cb is called only once +// See also: http://npm.im/once for this specific use case +var once = wrappy(function (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } +}) + +function printBoo () { + console.log('boo') +} +// has some rando property +printBoo.iAmBooPrinter = true + +var onlyPrintOnce = once(printBoo) + +onlyPrintOnce() // prints 'boo' +onlyPrintOnce() // does nothing + +// random property is retained! +assert.equal(onlyPrintOnce.iAmBooPrinter, true) +``` diff --git a/node_modules/wrappy/package.json b/node_modules/wrappy/package.json new file mode 100644 index 000000000..6f5904aec --- /dev/null +++ b/node_modules/wrappy/package.json @@ -0,0 +1,59 @@ +{ + "_from": "wrappy@1", + "_id": "wrappy@1.0.2", + "_inBundle": false, + "_integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "_location": "/wrappy", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "wrappy@1", + "name": "wrappy", + "escapedName": "wrappy", + "rawSpec": "1", + "saveSpec": null, + "fetchSpec": "1" + }, + "_requiredBy": [ + "/inflight", + "/once" + ], + "_resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "_shasum": "b5243d8f3ec1aa35f1364605bc0d1036e30ab69f", + "_spec": "wrappy@1", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/inflight", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/npm/wrappy/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Callback wrapping utility", + "devDependencies": { + "tap": "^2.3.1" + }, + "directories": { + "test": "test" + }, + "files": [ + "wrappy.js" + ], + "homepage": "https://github.com/npm/wrappy", + "license": "ISC", + "main": "wrappy.js", + "name": "wrappy", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/wrappy.git" + }, + "scripts": { + "test": "tap --coverage test/*.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/wrappy/wrappy.js b/node_modules/wrappy/wrappy.js new file mode 100644 index 000000000..bb7e7d6fc --- /dev/null +++ b/node_modules/wrappy/wrappy.js @@ -0,0 +1,33 @@ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} diff --git a/node_modules/xtend/.npmignore b/node_modules/xtend/.npmignore new file mode 100644 index 000000000..3c3629e64 --- /dev/null +++ b/node_modules/xtend/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/xtend/LICENCE b/node_modules/xtend/LICENCE new file mode 100644 index 000000000..a23e08a85 --- /dev/null +++ b/node_modules/xtend/LICENCE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Raynos. + +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. \ No newline at end of file diff --git a/node_modules/xtend/Makefile b/node_modules/xtend/Makefile new file mode 100644 index 000000000..d583fcf49 --- /dev/null +++ b/node_modules/xtend/Makefile @@ -0,0 +1,4 @@ +browser: + node ./support/compile + +.PHONY: browser \ No newline at end of file diff --git a/node_modules/xtend/README.md b/node_modules/xtend/README.md new file mode 100644 index 000000000..389adae38 --- /dev/null +++ b/node_modules/xtend/README.md @@ -0,0 +1,27 @@ +# xtend + +[![browser support][3]][4] + +Extend like a boss + +xtend is a basic utility library which allows you to extend an object by appending all of the properties from each object in a list. When there are identical properties, the right-most property takes presedence. + +## Examples + +```js +var extend = require("xtend") + +var combination = extend({ + a: "a" +}, { + b: "b" +}) +// { a: "a", b: "b" } +``` + + +## MIT Licenced + + + [3]: http://ci.testling.com/Raynos/xtend.png + [4]: http://ci.testling.com/Raynos/xtend diff --git a/node_modules/xtend/has-keys.js b/node_modules/xtend/has-keys.js new file mode 100644 index 000000000..62391e786 --- /dev/null +++ b/node_modules/xtend/has-keys.js @@ -0,0 +1,7 @@ +module.exports = hasKeys + +function hasKeys(source) { + return source !== null && + (typeof source === "object" || + typeof source === "function") +} diff --git a/node_modules/xtend/index.js b/node_modules/xtend/index.js new file mode 100644 index 000000000..20937d19a --- /dev/null +++ b/node_modules/xtend/index.js @@ -0,0 +1,25 @@ +var Keys = require("object-keys") +var hasKeys = require("./has-keys") + +module.exports = extend + +function extend() { + var target = {} + + for (var i = 0; i < arguments.length; i++) { + var source = arguments[i] + + if (!hasKeys(source)) { + continue + } + + var keys = Keys(source) + + for (var j = 0; j < keys.length; j++) { + var name = keys[j] + target[name] = source[name] + } + } + + return target +} diff --git a/node_modules/xtend/mutable.js b/node_modules/xtend/mutable.js new file mode 100644 index 000000000..17454ae40 --- /dev/null +++ b/node_modules/xtend/mutable.js @@ -0,0 +1,25 @@ +var Keys = require("object-keys") +var hasKeys = require("./has-keys") + +module.exports = extend + +function extend(target) { + var sources = [].slice.call(arguments, 1) + + for (var i = 0; i < sources.length; i++) { + var source = sources[i] + + if (!hasKeys(source)) { + continue + } + + var keys = Keys(source) + + for (var j = 0; j < keys.length; j++) { + var name = keys[j] + target[name] = source[name] + } + } + + return target +} diff --git a/node_modules/xtend/package.json b/node_modules/xtend/package.json new file mode 100644 index 000000000..1108774cd --- /dev/null +++ b/node_modules/xtend/package.json @@ -0,0 +1,93 @@ +{ + "_from": "xtend@~2.1.1", + "_id": "xtend@2.1.2", + "_inBundle": false, + "_integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "_location": "/xtend", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "xtend@~2.1.1", + "name": "xtend", + "escapedName": "xtend", + "rawSpec": "~2.1.1", + "saveSpec": null, + "fetchSpec": "~2.1.1" + }, + "_requiredBy": [ + "/through2" + ], + "_resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "_shasum": "6efecc2a4dad8e6962c4901b337ce7ba87b5d28b", + "_spec": "xtend@~2.1.1", + "_where": "/Users/timothyjoo/Turing/4mod/class_exercises/javascript-basics-challenge/node_modules/through2", + "author": { + "name": "Raynos", + "email": "raynos2@gmail.com" + }, + "bugs": { + "url": "https://github.com/Raynos/xtend/issues", + "email": "raynos2@gmail.com" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "Jake Verbaten" + }, + { + "name": "Matt Esch" + } + ], + "dependencies": { + "object-keys": "~0.4.0" + }, + "deprecated": false, + "description": "extend like a boss", + "devDependencies": { + "tape": "~1.1.0" + }, + "engines": { + "node": ">=0.4" + }, + "homepage": "https://github.com/Raynos/xtend", + "keywords": [ + "extend", + "merge", + "options", + "opts", + "object", + "array" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/raynos/xtend/raw/master/LICENSE" + } + ], + "main": "index", + "name": "xtend", + "repository": { + "type": "git", + "url": "git://github.com/Raynos/xtend.git" + }, + "scripts": { + "test": "node test" + }, + "testling": { + "files": "test.js", + "browsers": [ + "ie/7..latest", + "firefox/16..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest" + ] + }, + "version": "2.1.2" +} diff --git a/node_modules/xtend/test.js b/node_modules/xtend/test.js new file mode 100644 index 000000000..3369d7966 --- /dev/null +++ b/node_modules/xtend/test.js @@ -0,0 +1,63 @@ +var test = require("tape") +var extend = require("./") +var mutableExtend = require("./mutable") + +test("merge", function(assert) { + var a = { a: "foo" } + var b = { b: "bar" } + + assert.deepEqual(extend(a, b), { a: "foo", b: "bar" }) + assert.end() +}) + +test("replace", function(assert) { + var a = { a: "foo" } + var b = { a: "bar" } + + assert.deepEqual(extend(a, b), { a: "bar" }) + assert.end() +}) + +test("undefined", function(assert) { + var a = { a: undefined } + var b = { b: "foo" } + + assert.deepEqual(extend(a, b), { a: undefined, b: "foo" }) + assert.deepEqual(extend(b, a), { a: undefined, b: "foo" }) + assert.end() +}) + +test("handle 0", function(assert) { + var a = { a: "default" } + var b = { a: 0 } + + assert.deepEqual(extend(a, b), { a: 0 }) + assert.deepEqual(extend(b, a), { a: "default" }) + assert.end() +}) + +test("is immutable", function (assert) { + var record = {} + + extend(record, { foo: "bar" }) + assert.equal(record.foo, undefined) + assert.end() +}) + +test("null as argument", function (assert) { + var a = { foo: "bar" } + var b = null + var c = void 0 + + assert.deepEqual(extend(b, a, c), { foo: "bar" }) + assert.end() +}) + +test("mutable", function (assert) { + var a = { foo: "bar" } + + mutableExtend(a, { bar: "baz" }) + + assert.equal(a.bar, "baz") + assert.end() +}) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..cc8e449f2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,386 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=" + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bindings": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz", + "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=" + }, + "bl": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.4.2.tgz", + "integrity": "sha1-XbMdcvA4xU5orcOVeBJf47Ct3JY=", + "requires": { + "readable-stream": "1.0.34" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" + } + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "requires": { + "ansi-styles": "1.1.0", + "escape-string-regexp": "1.0.5", + "has-ansi": "0.1.0", + "strip-ansi": "0.3.0", + "supports-color": "0.2.0" + }, + "dependencies": { + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=" + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "deasync": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.12.tgz", + "integrity": "sha512-gpacYo8FBZh3INBp2KOtrQp9kCO5faHvOmEZx3/cZTr3Mm8/kAYs7/Ws3E3OAH0ApBNK6Y6N+7+Dka2Zn2Fldw==", + "requires": { + "bindings": "1.2.1", + "nan": "2.9.2" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "requires": { + "ansi-regex": "0.2.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.4.tgz", + "integrity": "sha512-nMOpAPFosU1B4Ix1jdhx5e3q7XO55ic5a8cgYvW27CequcEY+BabS0kUVL1Cw1V5PuVHZWeNRWFLmEPexo79VA==", + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.9.2.tgz", + "integrity": "sha512-ltW65co7f3PQWBDbqVvaU1WtFJUsNW7sWWm4HINhbMQIyVyzIeyZ8toX5TC5eeooE6piZoaEh4cZkueSKG3KYw==" + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pryjs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pryjs/-/pryjs-1.0.3.tgz", + "integrity": "sha1-msqACY7l3edrenu2047CrHIJR80=", + "requires": { + "chalk": "0.5.1", + "coffee-script": "1.12.7", + "deasync": "0.1.12", + "pygmentize-bundled": "2.3.0", + "underscore": "1.8.3" + } + }, + "pygmentize-bundled": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pygmentize-bundled/-/pygmentize-bundled-2.3.0.tgz", + "integrity": "sha1-1CXe2o0TaXW5M+3jYxNfYjNQgUo=", + "requires": { + "bl": "0.4.2", + "through2": "0.2.3" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "requires": { + "ansi-regex": "0.2.1" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "requires": { + "has-flag": "2.0.0" + } + }, + "through2": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", + "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", + "requires": { + "readable-stream": "1.1.14", + "xtend": "2.1.2" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + } + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "requires": { + "object-keys": "0.4.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..0d5a64e29 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "yes", + "version": "1.0.0", + "description": "In this challenge, you'll deepen your JavaScript fundamentals by completing a series of exercises. You'll need to follow the following steps to successfully complete this challenge:", + "main": "rectangles.js", + "directories": { + "test": "test" + }, + "dependencies": { + "chai": "^4.1.2", + "pryjs": "^1.0.3" + }, + "devDependencies": { + "mocha": "^5.0.4" + }, + "scripts": { + "test": "mocha" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Tyjoo26/javascript-basics-challenge.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/Tyjoo26/javascript-basics-challenge/issues" + }, + "homepage": "https://github.com/Tyjoo26/javascript-basics-challenge#readme" +} diff --git a/rectangles.js b/rectangles.js new file mode 100644 index 000000000..287a0adf1 --- /dev/null +++ b/rectangles.js @@ -0,0 +1,36 @@ +var pry = require('pryjs') + +var rectangle = {width: 10, height: 20} + +//area function +function area(shape){ + return shape.width * shape.height; +} +console.log(area(rectangle)) + +//perimeter function +function perimeter(shape){ + return ((shape.width * 2) + (shape.height * 2)) +} +console.log(perimeter(rectangle)) + +//diagonal function +function diagonal(shape) { + return Math.sqrt(squareCalculate(shape)) +} +//refactored out squareCalculation +function squareCalculate(shape) { + return ((Math.pow(shape.width, 2)) + (Math.pow(shape.height, 2))) +} + +//is quare calculation +function isSquare(shape) { + if (shape.width === shape.height) { + return true; + } + else return false; +} + + +// var rectangles = module.exports = {}; +module.exports = {area: area, perimeter: perimeter, diagonal : diagonal, isSquare :isSquare} diff --git a/test/rectangles-test.js b/test/rectangles-test.js new file mode 100644 index 000000000..70ae7da15 --- /dev/null +++ b/test/rectangles-test.js @@ -0,0 +1,39 @@ +var chai = require('chai'); +var assert = require('assert'); +var pry = require('pryjs') +var area = require("../rectangles").area +var perimeter = require("../rectangles").perimeter +var diagonal = require("../rectangles").diagonal +var isSquare = require("../rectangles").isSquare + +// is there way to declare global var rectangle so i dont have to put it in every test? + +describe("Rectangle Unit Test", function(){ + it("Area returns area of rectangle", function(){ + var rectangle = {width: 10, height: 20} + assert.equal(rectangle.width, 10 ); + assert.equal(rectangle.height, 20); + + assert.equal(area(rectangle), 200 ) + + }) + + it("perimeter returns perimeter of rectangle", function(){ + var rectangle = {width: 10, height: 20} + + assert.equal(perimeter(rectangle), 60 ) + }) + + it("diagonal returns diagonal of rectangle", function(){ + var rectangle = {width: 10, height: 20} + + assert.equal(diagonal(rectangle), 22.360679774997898 ) + }) + + it("isSquare returns true if rectangle is Gabe", function(){ + var rectangle = {width: 10, height: 20} + + assert.equal(isSquare(rectangle), false ) + }) + +}) From 584c9146c370c8b54e2562047048ad6a67704ba7 Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Mon, 12 Mar 2018 15:31:43 -0600 Subject: [PATCH 2/9] built triangle test and testjs file it passes --- rectangles.js | 3 +++ test/triangle-test.js | 23 +++++++++++++++++++++++ triangle.js | 21 +++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 test/triangle-test.js create mode 100644 triangle.js diff --git a/rectangles.js b/rectangles.js index 287a0adf1..7ae0828de 100644 --- a/rectangles.js +++ b/rectangles.js @@ -32,5 +32,8 @@ function isSquare(shape) { } + + + // var rectangles = module.exports = {}; module.exports = {area: area, perimeter: perimeter, diagonal : diagonal, isSquare :isSquare} diff --git a/test/triangle-test.js b/test/triangle-test.js new file mode 100644 index 000000000..d4991312f --- /dev/null +++ b/test/triangle-test.js @@ -0,0 +1,23 @@ +var chai = require('chai'); +var assert = require('assert'); +var pry = require('pryjs') +var isTriangle = require('../triangle').isTriangle + + +describe("Triangle unit test", function(){ + it("is not a valid triangle with zeros", function(){ + assert.equal(isTriangle(0,0,0), false) + }) + + it("is not a valid triangle with negative numbers", function(){ + assert.equal(isTriangle(1,2,-3), false) + }) + + it("is a valid triangle with positive numbers", function(){ + assert.equal(isTriangle(4,8,50), false) + }) + + it("is a valid triangle with positive numbers", function(){ + assert.equal(isTriangle(1,2,3), true) + }) +}) diff --git a/triangle.js b/triangle.js new file mode 100644 index 000000000..d261fbe81 --- /dev/null +++ b/triangle.js @@ -0,0 +1,21 @@ + + +function isTriangle(num1, num2, num3) { + if(num1 === 0 || num2 === 0 || num3 === 0) { + return false + } + if(num1 < 0 || num2 < 0 || num3 < 0) { + return false + } + if(num1 + num2 < num3 || num2 +num3 < num1 || num3 + num1 < num2){ + return false + } + else { + return true + } +} + + + + +module.exports = {isTriangle : isTriangle} From 11e2b7bf9f1214ac8716fa4988353b3dcfea787d Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Mon, 12 Mar 2018 15:42:07 -0600 Subject: [PATCH 3/9] build total function with test passing --- average.js | 15 +++++++++++++++ test/averages-test.js | 15 +++++++++++++++ triangle.js | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 average.js create mode 100644 test/averages-test.js diff --git a/average.js b/average.js new file mode 100644 index 000000000..b86f29907 --- /dev/null +++ b/average.js @@ -0,0 +1,15 @@ + + +var array = [ 1 ,3 ,4 ,5, 6] + +function total(data) { + var total = 0; + for (var i = 0; i < data.length ; i++){ + total += data[i]; + } + return total +} + + + +module.exports = {total : total} diff --git a/test/averages-test.js b/test/averages-test.js new file mode 100644 index 000000000..506e260fd --- /dev/null +++ b/test/averages-test.js @@ -0,0 +1,15 @@ +var chai = require('chai'); +var assert = require('assert'); +var pry = require('pryjs'); +var total = require('../average').total + + + + +describe("Numbers", function(){ + it("will return total of all array values", function(){ + var array = [ 1,3,4,5,6] + + assert.equal(total(array), 19) + }) +}) diff --git a/triangle.js b/triangle.js index d261fbe81..0993ed9e6 100644 --- a/triangle.js +++ b/triangle.js @@ -1,5 +1,5 @@ - +//how to refactor this ugly guy? function isTriangle(num1, num2, num3) { if(num1 === 0 || num2 === 0 || num3 === 0) { return false From c821abe0dc35a2fe269c3e2ab714d585fd987f69 Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Mon, 12 Mar 2018 19:49:05 -0600 Subject: [PATCH 4/9] factorial methodbuilt and test --- average.js | 49 ++++++++++++++++++++++++++++++++++++++++-- factorial.js | 9 ++++++++ test/averages-test.js | 29 ++++++++++++++++++++++++- test/factorial-test.js | 10 +++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 factorial.js create mode 100644 test/factorial-test.js diff --git a/average.js b/average.js index b86f29907..3659148bb 100644 --- a/average.js +++ b/average.js @@ -1,4 +1,4 @@ - +pry = require('pryjs') var array = [ 1 ,3 ,4 ,5, 6] @@ -10,6 +10,51 @@ function total(data) { return total } +function mean(data){ + var sum = 0 ; + for (var i = 0; i < data.length ; i++){ + sum += data[i]; + } + return (sum / data.length) +} + +////////// + +function reOrganize(array, index, newIndex) { + var temp = array[index]; + array[index] = array[newIndex]; + array[newIndex] = temp; +} + +function bubbleSort(array){ + for( var index = 0 ; index < array.length; index++){ + for(var newIndex = 1; newIndex < array.length; newIndex++){ + if(array[newIndex-1] > array[newIndex]){ + reOrganize(array, newIndex-1, newIndex); + } + } + } + return array +} + + +function median(data){ + let median = 0; + let length = data.length; + data.sort(); + if (length % 2 === 0) { + median = (data[length / 2 - 1] + data[length / 2]) / 2; + } else { + median = data[(length - 1) / 2]; + } + return median; +} + +function mode(data) { + +} + + -module.exports = {total : total} +module.exports = {total : total, mean: mean, median: median, mode: mode} diff --git a/factorial.js b/factorial.js new file mode 100644 index 000000000..89e5f31aa --- /dev/null +++ b/factorial.js @@ -0,0 +1,9 @@ +function factorial(num){ + if(num == 0) + return 1; + else { + return (num * factorial(num-1)); + } +} + +modules.export = [factorial:factorial] diff --git a/test/averages-test.js b/test/averages-test.js index 506e260fd..96c085f5b 100644 --- a/test/averages-test.js +++ b/test/averages-test.js @@ -2,7 +2,9 @@ var chai = require('chai'); var assert = require('assert'); var pry = require('pryjs'); var total = require('../average').total - +var mean = require('../average').mean +var median = require('../average').median +var mode = require('../average').mode @@ -12,4 +14,29 @@ describe("Numbers", function(){ assert.equal(total(array), 19) }) + + + it("will return mean of all array values", function(){ + var array = [ 1,3,4,5,6] + + assert.equal(mean(array), 3.8) + }) + + it("will return median of all array values in array of odd length", function(){ + var array = [ 1,3,4,5,6] + + assert.equal(median(array), 4) + }) + + it("will return median of all array values in array of even length", function(){ + var array = [ 1,3,4,5,6, 1] + + assert.equal(median(array), 3.5) + }) + + it("will return mode of array", function(){ + var array = [ 1, 2, 3, 2, 4, 5, 6, 7, 2] + + assert.equal(mode(array), 2) + }) }) diff --git a/test/factorial-test.js b/test/factorial-test.js new file mode 100644 index 000000000..f20c74021 --- /dev/null +++ b/test/factorial-test.js @@ -0,0 +1,10 @@ +var chai = require('chai'); +var assert = require('assert'); +var pry = require('pryjs'); +var factorial = require('../factorial').factorial + + +describe("Factorial unit test", function(){ + it("returns factorial amount", function(){ + assert.equal(factorial(5), 120) +}) From 141eb39022d96e17e366d022e09c00ad881a150c Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Tue, 13 Mar 2018 09:53:26 -0600 Subject: [PATCH 5/9] commit for turn in --- average.js | 12 ++++++------ factorial.js | 8 ++++---- test/factorial-test.js | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/average.js b/average.js index 3659148bb..d7ea5429d 100644 --- a/average.js +++ b/average.js @@ -39,8 +39,8 @@ function bubbleSort(array){ function median(data){ - let median = 0; - let length = data.length; + median = 0; + length = data.length; data.sort(); if (length % 2 === 0) { median = (data[length / 2 - 1] + data[length / 2]) / 2; @@ -49,10 +49,10 @@ function median(data){ } return median; } - -function mode(data) { - -} +// +// function mode(data) { +// +// } diff --git a/factorial.js b/factorial.js index 89e5f31aa..73fbc2db0 100644 --- a/factorial.js +++ b/factorial.js @@ -1,9 +1,9 @@ -function factorial(num){ +function factor(num){ if(num == 0) return 1; else { - return (num * factorial(num-1)); + return (num * factor(num-1)); } -} +}; -modules.export = [factorial:factorial] +module.export = {factor: factor} diff --git a/test/factorial-test.js b/test/factorial-test.js index f20c74021..b404debc7 100644 --- a/test/factorial-test.js +++ b/test/factorial-test.js @@ -1,10 +1,10 @@ var chai = require('chai'); var assert = require('assert'); var pry = require('pryjs'); -var factorial = require('../factorial').factorial +var factor = require('../factorial').factor describe("Factorial unit test", function(){ it("returns factorial amount", function(){ assert.equal(factorial(5), 120) -}) +})}); From ac0ef6d51d0ad871f3dcf33b5ef347aed1671160 Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Tue, 13 Mar 2018 17:07:38 -0600 Subject: [PATCH 6/9] factorial test pass --- average.js | 25 +++++++++++++++++++++---- factorial.js | 6 +++--- test/factorial-test.js | 4 ++-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/average.js b/average.js index d7ea5429d..363595384 100644 --- a/average.js +++ b/average.js @@ -49,10 +49,27 @@ function median(data){ } return median; } -// -// function mode(data) { -// -// } + +function mode(data) { + var counter = {}; + var check = 0; + var result; + for (var i = 0; i < data.length; i++) { + var number = data[i]; + + if (counter[number] === undefined){ + counter[number] = 1; + } else { + counter[number] = counter[number] + 1; + } + if(counter[number] > check){ + check = counter[number]; + result = data[i]; + } + } + //ask lovisa about this if block + return result; +} diff --git a/factorial.js b/factorial.js index 73fbc2db0..9eae66419 100644 --- a/factorial.js +++ b/factorial.js @@ -1,9 +1,9 @@ -function factor(num){ +function factorial(num){ if(num == 0) return 1; else { - return (num * factor(num-1)); + return (num * factorial(num-1)); } }; -module.export = {factor: factor} +module.exports = {factorial: factorial} diff --git a/test/factorial-test.js b/test/factorial-test.js index b404debc7..68d7c6819 100644 --- a/test/factorial-test.js +++ b/test/factorial-test.js @@ -1,10 +1,10 @@ var chai = require('chai'); var assert = require('assert'); var pry = require('pryjs'); -var factor = require('../factorial').factor +var factorial = require('../factorial').factorial describe("Factorial unit test", function(){ - it("returns factorial amount", function(){ + it("returns factorialial amount", function(){ assert.equal(factorial(5), 120) })}); From d1bbbe7f391de3a08b21cd25b093aacb0de76fb7 Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Wed, 14 Mar 2018 08:03:54 -0600 Subject: [PATCH 7/9] finished longest string function --- longest.js | 24 ++++++++++++++++++++++++ test/longest-test.js | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 longest.js create mode 100644 test/longest-test.js diff --git a/longest.js b/longest.js new file mode 100644 index 000000000..bc969bd35 --- /dev/null +++ b/longest.js @@ -0,0 +1,24 @@ +var pry = require('pryjs'); + +var animals = ["manbearpig", "manimal", "donkey", "tiger"] + + + +function longest(data){ + var tempLongest = undefined + if(data.length === 0) { + return undefined; + } + data.forEach(string => { + if (tempLongest === undefined){ + tempLongest = string; + } + else if (string.length > tempLongest.length){ + tempLongest = string; + } + }) + return tempLongest; + } + + +module.exports = {longest: longest} diff --git a/test/longest-test.js b/test/longest-test.js new file mode 100644 index 000000000..692dc091d --- /dev/null +++ b/test/longest-test.js @@ -0,0 +1,19 @@ +var chai = require('chai'); +var assert = require('assert'); +var pry = require('pryjs'); +var longest = require('../longest').longest + + +describe("Longest string check", function(){ + it("will give you the longest string in array", function(){ + var animals = ["manbearpig", "manimal", "donkey", "tiger"] + + assert.equal(longest(animals), "manbearpig") + }) + + it("will give you the undefined if array is empty", function(){ + var poop = [] + + assert.equal(longest(poop), undefined) + }) +}) From 79a1c406c139131b206bb11ee79e76ce97f8a4e5 Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Wed, 14 Mar 2018 08:05:07 -0600 Subject: [PATCH 8/9] refactored longest function, test passes --- longest.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/longest.js b/longest.js index bc969bd35..3c361a252 100644 --- a/longest.js +++ b/longest.js @@ -6,14 +6,8 @@ var animals = ["manbearpig", "manimal", "donkey", "tiger"] function longest(data){ var tempLongest = undefined - if(data.length === 0) { - return undefined; - } data.forEach(string => { - if (tempLongest === undefined){ - tempLongest = string; - } - else if (string.length > tempLongest.length){ + if (tempLongest === undefined || string.length > tempLongest.length){ tempLongest = string; } }) From 9a67bc09ea9513fef992151bb01792091c7f931b Mon Sep 17 00:00:00 2001 From: Tyjoo26 Date: Wed, 14 Mar 2018 08:34:42 -0600 Subject: [PATCH 9/9] Finalized table function --- table.js | 21 +++++++++++++++++++++ test/table-test.js | 11 +++++++++++ 2 files changed, 32 insertions(+) create mode 100644 table.js create mode 100644 test/table-test.js diff --git a/table.js b/table.js new file mode 100644 index 000000000..2956a8017 --- /dev/null +++ b/table.js @@ -0,0 +1,21 @@ +var pry = require('pryjs'); + + + +function table(num){ + var table = [] + for(var a = 1; a <= num; a++){ + var oneRow = [] + for(var b = 1; b <= num; b++) { + oneRow.push(b * a); + eval(pry.it) + } + table.push(oneRow.join(" ")); + } + return table.join("\n"); +} + + + + +module.exports = {table: table} diff --git a/test/table-test.js b/test/table-test.js new file mode 100644 index 000000000..4c917ce1d --- /dev/null +++ b/test/table-test.js @@ -0,0 +1,11 @@ +var chai = require('chai'); +var assert = require('assert'); +var pry = require('pryjs'); +var table = require('../table').table + + +describe("Times table unit test", function(){ + it("returns a long string with newlines", function(){ + assert.equal(table(5), "1 2 3 4 5\n2 4 6 8 10\n3 6 9 12 15\n4 8 12 16 20\n5 10 15 20 25") + }) +})